Generating Rows and Columns dynamically based on xml data

Hi, I was working with sfdatagrid to create table with dynamic rows and columns but couldn't succeed. Could you provide an example to how to generate the table. Given below is an example for xml data.(the column name and number of columns will vary)

<DATA_DS>

<ROWSET>

<ROW>

<ABSENCE_AGREEMENT_ID>1</ABSENCE_AGREEMENT_ID>

<EVENT_TYPE_CD></EVENT_TYPE_CD>

<BASE_NAME>LEAVE_US</BASE_NAME>

<ENTERPRISE_ID>1</ENTERPRISE_ID>

<LEGISLATION_CODE>US</LEGISLATION_CODE>

</ROW>

<ROW>

<ABSENCE_AGREEMENT_ID>2</ABSENCE_AGREEMENT_ID>

<EVENT_TYPE_CD>PLC</EVENT_TYPE_CD>

<BASE_NAME>B AGREEMENT_US</BASE_NAME>

<ENTERPRISE_ID>1</ENTERPRISE_ID>

<LEGISLATION_CODE>US</LEGISLATION_CODE>

</ROW>

</ROWSET>

</DATA_DS>



5 Replies

TP Tamilarasan Paranthaman Syncfusion Team September 15, 2023 01:27 PM UTC

Hi Sarath Chandran,


As per the DataGrid structure, when creating a table, it's essential to ensure that the number of cells in a row matches the number of columns in the DataGrid. If you add columns at runtime, you should rebuild the DataGridRow with the same number of cells to maintain consistency.


We have provided a sample for creating a DataGrid from the provided XML code. In this sample, we utilized the XML package to parse the XML data into columns and data lists. However, you can use any package or your custom logic to convert XML data. In that sample, we get the column and row values from the XML data and create the column and data source based on that. Please refer to the following sample for detailed information.


Sample Link: https://www.syncfusion.com/downloads/support/directtrac/general/ze/sample-445335168




Regards,

Tamilarasan



SC SARATH CHANDRAN September 19, 2023 06:09 AM UTC

Thanks Tamilarasan for the reply. My requirement is to create a table at the runtime. The table structure will vary at each runtime. Could you give an example to how to rebuild the DataGridRow for the above requirement?



TP Tamilarasan Paranthaman Syncfusion Team September 20, 2023 01:27 PM UTC

Sarath Chandran,


You can rebuild the rows by creating new rows and mapping them to the `DataGridRows.rows` property. It's essential to ensure that the number of columns matches the number of cells in each row. We have attached a simple sample that demonstrates how to change the source at runtime through a button click. In this sample, we dynamically alter the source and rebuild the data source with the respective collection.


Please note that we haven't mapped the XML data to the underlying collection in this example, as your requirement is for dynamic data. Instead, we directly map the values to the DataGrid cells based on the index. For further details, please refer to the following sample and code snippet.


 

class MyHomePageState extends State<MyHomePage> {

 

int index = 1;

 

  @override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(title: const Text('Syncfusion DataGrid Demo')),

      body: Column(

        children: [

          Padding(

            padding: const EdgeInsets.symmetric(vertical: 20),

            child: ElevatedButton(

                onPressed: () {

                  String datasource;

                  int newIndex;

                  if (index == 1) {

                    datasource = xmlData2;

                    newIndex = 2;

                  } else if (index == 2) {

                    datasource = xmlData3;

                    newIndex = 0;

                  } else {

                    datasource = xmlData1;

                    newIndex = 1;

                  }

 

                  setState(() {

                    document = XmlDocument.parse(datasource);

                    columnNames = getColumnNames();

                    dataList = getDataList(document);

                    getColumns = columnNames

                        .map((name) => GridColumn(

                            columnName: name,

                            label: Container(

                              alignment: Alignment.center,

                              child: Text(name.toString()),

                            )))

                        .toList();

                    // To rebuild the data source with new data

                    _productDataSource.buildDataGridRows(columnNames);

 

                    // instead, you can also create new instance of data source

                    // _productDataSource = ProductDataSource(columnNames: columnNames);

                  });

 

                  index = newIndex;

                },

                child: const Text('Change XML Data Source')),

          ),

          SfDataGrid(

            source: _productDataSource,

            columns: getColumns,

            columnWidthMode: ColumnWidthMode.fill,

          ),

        ],

      ),

    );

  }

 

In DataGridSource:

class ProductDataSource extends DataGridSource {

  ProductDataSource({required List<String> columnNames}) {

    buildDataGridRows(columnNames);

  }

 

  // Local variable to hold the row data

  List<DataGridRow> dataGridRows = [];

 

  // The collection of rows to display in [SfDataGrid].

  @override

  List<DataGridRow> get rows => dataGridRows;

 

  // Building DataGridRows

  void buildDataGridRows(List<String> columnNames) {

    dataGridRows = dataList

        .map((data) => DataGridRow(

            cells: List.generate(

                columnNames.length,

                (index) => DataGridCell(

                    columnName: columnNames[index], value: data[index]))))

        .toList();

  }

}


Sample Link: https://www.syncfusion.com/downloads/support/directtrac/general/ze/Sample-121142540



SC SARATH CHANDRAN October 17, 2023 05:56 AM UTC

Thankyou  Tamilarasan.



TP Tamilarasan Paranthaman Syncfusion Team October 18, 2023 07:56 AM UTC

Sarath Chandran,


We are glad that the provided response meets your requirement. Please let us know if you require further assistance. As always, we are happy to help you out.



Loader.
Up arrow icon