PDA

View Full Version : [CLOSED] dynamically adding columns to gridpanel



sharmav1
Jun 25, 2015, 2:37 PM
I have a grid panel like the one below(provided view code), now I want to add some more columns to it dynamically. To be more precise, I have some data columns coming from server and those are now configured into a datatable, and now that datatable columns need to be merged with the columns of the gridpanel (these grid panel columns are created in markup and the data coming from database) at the runtime and then loaded. Also, I have no information on data columns coming from data table(like column name and column data type), means I have to check the data table first, iterate over each column and then fetch their names and datatype at runtime which is then added to gridpanel. So , anyone please help me how to do that? Thanks


view code:

X.GridPanel().Title("Update Grid").ID("updateGrid").Layout(LayoutType.Fit).Flex(7).Border(false).Aut oScroll(true).Region(Region.Center)
.Store
(
X.Store().ID("updateStore").Sorters(X.DataSorter().Property("Name").Direction(Ext.Net.SortDirection.ASC))
.Model
(
X.Model()
.Fields
(
new ModelField("Id", ModelFieldType.Object),
new ModelField("Name", ModelFieldType.String),

new ModelField("IsEnabled", ModelFieldType.Boolean),

new ModelField("Status", ModelFieldType.String)

)
)

)
.ColumnModel
(
X.Column().Text("Name").DataIndex("Name")
.HeaderItems(
X.TextField().ID("hdrName").Listeners(l => { l.Change.Handler = "jsApplyFilter(this);"; l.Change.Buffer = 250; }).Plugins(X.ClearButton())
),
X.Column().Text("Status").DataIndex("Status").HeaderItems(
X.TextField().ID("hdrStatus").Listeners(l => { l.Change.Handler = "jsApplyFilter(this);"; l.Change.Buffer = 250; }).Plugins(X.ClearButton())
),
X.ComponentColumn().Text("IsEnabled").DataIndex("IsEnabled").Editor(true).Align(Alignment.Center)
.HeaderItems(
Html.X().Container().Layout(LayoutType.VBox).Layou tConfig(new VBoxLayoutConfig { Align = VBoxAlign.Center })
.Items(
Html.X().Button()
.ID("Update")
.Icon(Icon.GroupEdit)
.ToolTip("Update All")
.Listeners(li => { li.Click.Handler = "UpdateAll();"; })
)
)
.Component
(
X.Checkbox()
),
X.ImageCommandColumn().ToolTip("Edit").Commands
(
X.ImageCommand().CommandName("Edit").Icon(Icon.TableEdit).Text("Edit")
)
.Listeners(l => { l.Command.Handler = "EditData(record.data);"; }),

X.ImageCommandColumn().ToolTip("Update").Text("Update").Commands
(
X.ImageCommand().CommandName("Update").Icon(Icon.TableAdd).Text("Update")
)
.Listeners(l => { l.Command.Handler = "UpdateRecord(record.data);"; })
)

Dimitris
Jun 25, 2015, 5:04 PM
Hi,

The following example shows how you can add three extra columns to the Model from the controller. The columns are defined in a DataTable.

View



@model System.Collections.IEnumerable

@{
Layout = null;
var X = Html.X();
}

<!DOCTYPE html>

<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>GridDynamicColumns</title>
</head>
<body>
@(X.ResourceManager())

@(X.GridPanel()
.Title("Update Grid")
.ID("updateGrid")
.Width(600)
.Height(350)
.Store(X.Store()
.ID("updateStore")
.Sorters(X.DataSorter().Property("Name")
.Direction(Ext.Net.SortDirection.ASC))
.Model(X.Model()
.Fields(
new ModelField("Id", ModelFieldType.Object),
new ModelField("Name", ModelFieldType.String),
new ModelField("IsEnabled", ModelFieldType.Boolean),
new ModelField("Status", ModelFieldType.String)
)
)
.DataSource(Model)
)
.ColumnModel(
X.Column().Text("Name").DataIndex("Name").Flex(1),
X.Column().Text("Status").DataIndex("Status"),
X.ComponentColumn().Text("IsEnabled").DataIndex("IsEnabled").Editor(true).Align(Alignment.Center)
.Component(
X.Checkbox()
),
X.ImageCommandColumn().ToolTip("Edit").Text("Edit").Commands(
X.ImageCommand()
.CommandName("Edit")
.Icon(Icon.TableEdit)
.Text("Edit")
),
X.ImageCommandColumn().ToolTip("Update").Text("Update").Commands(
X.ImageCommand()
.CommandName("Update")
.Icon(Icon.TableAdd)
.Text("Update")
)
)
)
</body>
</html>



Model



using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using Ext.Net;

namespace Mvc2.Models
{
public class DataModel
{
public static DataTable GetDataTable()
{
// data table dummy
DataTable dt = new DataTable();

dt.Columns.AddRange(new DataColumn[3] {
new DataColumn("Id"),
new DataColumn("Username"),
new DataColumn("Password")
});

dt.Rows.Add(1, "user1", "pwd1");
dt.Rows.Add(2, "user2", "pwd2");
dt.Rows.Add(3, "user3", "pwd3");

return dt;
}

public static void AddColumns(Store store, GridPanel grid)
{
DataTable table = DataModel.GetDataTable();

foreach (DataColumn col in table.Columns)
{
ModelField field = new ModelField(col.ColumnName);

store.AddField(field);

Column gridCol = new Column();
gridCol.Text = col.ColumnName;
gridCol.DataIndex = col.ColumnName;

grid.AddColumn(gridCol);
}
}

public static IEnumerable GetData()
{
DataTable table = DataModel.GetDataTable();

List<object> data = new List<object>();

foreach (DataRow row in table.Rows)
{
bool condition = Convert.ToInt32(row["Id"]) % 2 == 0;

data.Add(new object[] {
row["Id"].ToString(),
"Name " + row["Id"],
condition,
(condition) ? "Active" : "Inactive",
row["Id"].ToString(),
row["Username"],
row["Password"]
});
}

return data;
}
}
}


Controller



public ActionResult Index()
{
Store store = this.GetCmp<Store>("updateStore");

GridPanel grid = this.GetCmp<GridPanel>("updateGrid");

DataModel.AddColumns(store, grid);

return View(DataModel.GetData());
}



Hope it helps.

sharmav1
Jun 26, 2015, 1:05 PM
Hi @Dimitris,

Thanks for your reply. I followed your solution, but, I am still stuck at one place.

The below code(highlighted), is iterating over rows collection and storing the row data based on the column name into "data" list collection, but in my case I don't know the column names, and it's also possible that datatable columns may keep varying, means the columns are not fixed and can be added or removed any time.
Once my List<object> is ready I need to merge this data with the data inside another generic List of some type which will be returned back to the view to populate in the gridpanel.

Thanks



public static IEnumerable GetData()
{
DataTable table = DataModel.GetDataTable();

List<object> data = new List<object>();

foreach (DataRow row in table.Rows)
{
bool condition = Convert.ToInt32(row["Id"]) % 2 == 0;


data.Add(new object[] {
row["Id"].ToString(),
"Name " + row["Id"],
condition,
(condition) ? "Active" : "Inactive",
row["Id"].ToString(),
row["Username"],
row["Password"]
});
}

return data;
}

Dimitris
Jun 27, 2015, 10:41 PM
The below code(highlighted), is iterating over rows collection and storing the row data based on the column name into "data" list collection, but in my case I don't know the column names, and it's also possible that datatable columns may keep varying, means the columns are not fixed and can be added or removed any time.



using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using Ext.Net;

namespace Mvc2.Models
{
public class DataModel
{
public static DataTable GetDataTable()
{
// data table dummy
DataTable dt = new DataTable();

dt.Columns.AddRange(new DataColumn[3] {
new DataColumn("Id"),
new DataColumn("Username"),
new DataColumn("Password")
});

dt.Rows.Add(1, "user1", "pwd1");
dt.Rows.Add(2, "user2", "pwd2");
dt.Rows.Add(3, "user3", "pwd3");

return dt;
}

public static void AddColumns(Store store, GridPanel grid)
{
DataTable table = DataModel.GetDataTable();

foreach (DataColumn col in table.Columns)
{
ModelField field = new ModelField(col.ColumnName);

store.AddField(field);

Column gridCol = new Column();
gridCol.Text = col.ColumnName;
gridCol.DataIndex = col.ColumnName;

grid.AddColumn(gridCol);
}
}

public static IEnumerable GetData()
{
DataTable table = DataModel.GetDataTable();

List<object> data = new List<object>();

int columns = table.Columns.Count;

foreach (DataRow row in table.Rows)
{
bool condition = Convert.ToInt32(row[0]) % 2 == 0;

object[] obj = new object[columns+4];

// known columns
obj[0] = row[0].ToString();
obj[1] = "Name " + row[0];
obj[2] = condition;
obj[3] = (condition) ? "Active" : "Inactive";

// unknown columns
for (int i = 0; i < columns; i++)
{
obj[i+4] = row[i];
}

data.Add(obj);
}

return data;
}
}
}



Once my List<object> is ready I need to merge this data with the data inside another generic List of some type which will be returned back to the view to populate in the gridpanel.

The example above kind of merges some known and unknown columns into a data object. How you are going to merge data is entirely up to you and depends on the logic of your application.