Insert operation
Generally, there are three common techniques to insert grid row with InPlace and EditForms edit mode:
- Enabling the automatic operations for the control - this is a codeless approach and requires zero lines of code (see this online demo for more info).
- Use the ExtractValuesFromItem(dictonaryObject, editedItem) method (available since version 3.0 of Telerik RadGrid). You can create an empty dictionary object and pass it as first parameter of the ExtractValuesFromItem() method to extract the values from the inserted item (which is the second parameter to that method). The dictionary object will hold key -> value pairs where each key will be the DataField of the insertion field column and the corresponding value will be the data entered by the user.
- Fetch the data from each editor field individually through the auto-generated column editors. For this purpose you will need to iterate through the editable fields for the inserted grid row and modify the grid source on every loop.
The code below demonstrates the both approaches about how to perform the insert operation in Telerik RadGrid when the user presses the Insert button from the insertion form (thus firing the InsertCommand event).
 |
Note that we use the ViewState property (named GridSource) to update the grid source |
| ASPX/ASCX |
Copy Code |
|
<rad:RadGrid id="RadGrid1" runat="server"> <MasterTableView AutoGenerateColumns="False"> <Columns> <rad:GridBoundColumn HeaderText="OrderID" DataField="OrderID" ReadOnly="True" UniqueName="OrderID" Display= "False"></rad:GridBoundColumn> <rad:GridBoundColumn HeaderText="EmployeeID" DataField="EmployeeID" UniqueName="EmployeeID"></rad:GridBoundColumn> <rad:GridBoundColumn HeaderText="OrderDate" DataField="OrderDate" UniqueName="OrderDate"></rad:GridBoundColumn> <rad:GridBoundColumn HeaderText="ShipName" DataField="ShipName" UniqueName="ShipName"></rad:GridBoundColumn> <rad:GridEditCommandColumn UniqueName="EditCommandColumn"></rad:GridEditCommandColumn> </Columns> </MasterTableView> </rad:RadGrid> <asp:Label id="Label1" style="Z-INDEX: 102; LEFT: 744px; POSITION: absolute; TOP: 56px" runat="server"></asp:Label> |
1)
| C# |
Copy Code |
|
private DataTable GridSource { get { Object obj = this.ViewState["_gds"]; if(obj != null) { return (DataTable)obj; } else { DataTable table = DataSourceHelperCS.GetDataTable("SELECT TOP 10 OrderID, EmployeeID, OrderDate, ShipName FROM Orders"); this.ViewState[ "_gds"] = table; return table; } } } private void RadGrid1_NeedDataSource(object source, Telerik.WebControls.GridNeedDataSourceEventArgs e) { RadGrid1.DataSource = this.GridSource; } private void RadGrid1_InsertCommand(object source, Telerik.WebControls.GridCommandEventArgs e) { GridEditableItem editedItem = e.Item as GridEditableItem; DataTable ordersTable = this.GridSource;
DataRow newRow = ordersTable.NewRow();
//As this example demonstrates only in-memory editing, a new primary key value should be generated //This should not be applied when updating directly the database DataRow[] allValues = ordersTable.Select( "", "OrderID", DataViewRowState.CurrentRows ); if (allValues.Length > 0) { newRow["OrderID"] = (int)allValues[allValues.Length - 1]["OrderID"] + 1; } else { newRow["OrderID"] = 1; //the table is empty; }
//Set new values Hashtable newValues = new Hashtable(); //The GridTableView will fill the values from all editable columns in the hash e.Item.OwnerTableView.ExtractValuesFromItem(newValues, editedItem);
try { foreach( DictionaryEntry entry in newValues ) { newRow[(string)entry.Key] = entry.Value; } } catch( Exception ex ) { Label1.Text += "Unable to insert into Orders. Reason: " + ex.Message; e.Canceled = true; }
ordersTable.Rows.Add( newRow ); //Code for updating the database ca go here...
Label1.Text += "Order " + newRow["OrderID"] + " inserted" ;
} |
| VB.NET |
Copy Code |
|
Private ReadOnly Property GridSource As DataTable Get Dim obj As Object = Me.ViewState("_gds") If (Not (obj) Is Nothing) Then Return CType(obj,DataTable) Else Dim table As DataTable = DataSourceHelperVB.GetDataTable("SELECT TOP 10 OrderID, EmployeeID, OrderDate, ShipName FROM Orders") Me.ViewState("_gds") = table Return table End If End Get End Property
Private Sub RadGrid1_NeedDataSource(ByVal source As Object, ByVal e As Telerik.WebControls.GridNeedDataSourceEventArgs) RadGrid1.DataSource = Me.GridSource End Sub
Private Sub RadGrid1_InsertCommand(ByVal source As Object, ByVal e As Telerik.WebControls.GridCommandEventArgs) Dim editedItem As GridEditableItem = CType(e.Item,GridEditableItem) Dim ordersTable As DataTable = Me.GridSource Dim newRow As DataRow = ordersTable.NewRow Dim allValues() As DataRow = ordersTable.Select("", "OrderID", DataViewRowState.CurrentRows) If (allValues.Length > 0) Then newRow("OrderID") = (CType(allValues((allValues.Length - 1))("OrderID"), Integer) + 1) Else newRow("OrderID") = 1 End If Dim newValues As Hashtable = New Hashtable e.Item.OwnerTableView.ExtractValuesFromItem(newValues, editedItem) Try For Each entry As DictionaryEntry In newValues newRow(CType(entry.Key, String)) = entry.Value Next Catch ex As Exception Label1.Text = (Label1.Text + ("Unable to insert into Orders. Reason: " + ex.Message)) e.Canceled = true End Try ordersTable.Rows.Add(newRow) Label1.Text = (Label1.Text + ("Order " _ + (newRow("OrderID") + " inserted"))) End Sub |
2)
| C# |
Copy Code |
|
private DataTable GridSource { get { Object obj = this.ViewState["_gds"]; if(obj != null) { return (DataTable)obj; } else { DataTable table = DataSourceHelperCS.GetDataTable("SELECT TOP 10 OrderID, EmployeeID, OrderDate, ShipName FROM Orders"); this.ViewState[ "_gds"] = table; return table; } } } private void RadGrid1_NeedDataSource(object source, Telerik.WebControls.GridNeedDataSourceEventArgs e) { RadGrid1.DataSource = this.GridSource; } private void RadGrid1_InsertCommand(object source, Telerik.WebControls.GridCommandEventArgs e) { GridEditableItem editedItem = e.Item as GridEditableItem; GridEditManager editMan = editedItem.EditManager; DataTable ordersTable = this.GridSource;
DataRow newRow = ordersTable.NewRow();
//As this example demonstrates only in-memory editing, a new primary key value should be generated //This should not be applied when updating directly the database DataRow[] allValues = ordersTable.Select( "", "OrderID", DataViewRowState.CurrentRows ); if (allValues.Length > 0) { newRow["OrderID"] = (int)allValues[allValues.Length - 1]["OrderID"] + 1; } else { newRow["OrderID"] = 1; //the table is empty; }
//Set new values
foreach( GridColumn column in e.Item.OwnerTableView.RenderColumns) { if ( column is IGridEditableColumn ) { IGridEditableColumn editableCol = (column as IGridEditableColumn); if ( editableCol.IsEditable ) { IGridColumnEditor editor = editMan.GetColumnEditor( editableCol );
string editorText = "unknown"; object editorValue = null;
if ( editor is GridTextColumnEditor ) { editorText = (editor as GridTextColumnEditor).Text; editorValue = (editor as GridTextColumnEditor).Text; }
if ( editor is GridBoolColumnEditor ) { editorText = (editor as GridBoolColumnEditor).Value.ToString(); editorValue = (editor as GridBoolColumnEditor).Value; }
if ( editor is GridDropDownColumnEditor ) { editorText = (editor as GridDropDownColumnEditor).SelectedText + "; " + (editor as GridDropDownColumnEditor).SelectedValue; editorValue = (editor as GridDropDownColumnEditor).SelectedValue; }
try { newRow[column.UniqueName] = editorValue; } catch( Exception ex ) { Label1.Text += "Unable to insert into Orders. Reason: " + ex.Message; e.Canceled = true; } } } }
ordersTable.Rows.Add(newRow); this.GridSource.AcceptChanges();
//Code for updating the database ca go here...
Label1.Text += "Order " + newRow["OrderID"] + " inserted" ;
} |
| VB.NET |
Copy Code |
|
Private ReadOnly Property GridSource As DataTable Get Dim obj As Object = Me.ViewState("_gds") If (Not (obj) Is Nothing) Then Return CType(obj,DataTable) Else Dim table As DataTable = DataSourceHelperVB.GetDataTable("SELECT TOP 10 OrderID, EmployeeID, OrderDate, ShipName FROM Orders") Me.ViewState("_gds") = table Return table End If End Get End Property Private Sub RadGrid1_NeedDataSource(ByVal source As Object, ByVal e As Telerik.WebControls.GridNeedDataSourceEventArgs) RadGrid1.DataSource = Me.GridSource End Sub Private Sub RadGrid1_InsertCommand(ByVal source As Object, ByVal e As Telerik.WebControls.GridCommandEventArgs) Dim editedItem As GridEditableItem = CType(e.Item,GridEditableItem) Dim editMan As GridEditManager = editedItem.EditManager Dim ordersTable As DataTable = Me.GridSource
Dim newRow As DataRow = ordersTable.NewRow
Dim allValues() As DataRow = ordersTable.Select("", "OrderID", DataViewRowState.CurrentRows) If (allValues.Length > 0) Then newRow("OrderID") = (CType(allValues((allValues.Length - 1))("OrderID"), Integer) + 1) Else newRow("OrderID") = 1 End If Dim column As GridColumn For Each column In e.Item.OwnerTableView.Columns If TypeOf column Is IGridEditableColumn Then Dim editableCol As IGridEditableColumn = CType(column, IGridEditableColumn)
If (editableCol.IsEditable) Then Dim editor As IGridColumnEditor = editMan.GetColumnEditor(editableCol) Dim editorText As String = "unknown" Dim editorValue As Object = Nothing If (TypeOf editor Is GridTextColumnEditor) Then editorText = CType(editor, GridTextColumnEditor).Text editorValue = CType(editor, GridTextColumnEditor).Text End If If (TypeOf editor Is GridBoolColumnEditor) Then editorText = CType(editor, GridBoolColumnEditor).Value.ToString() editorValue = CType(editor, GridBoolColumnEditor).Value End If If (TypeOf editor Is GridDropDownColumnEditor) Then editorText = CType(editor, GridDropDownColumnEditor).SelectedText + "; " + CType(editor, GridDropDownColumnEditor).SelectedValue editorValue = CType(editor, GridDropDownColumnEditor).SelectedValue End If Try newRow(column.UniqueName) = editorValue Catch ex As Exception Label1.Text = (Label1.Text + ("Unable to insert into Orders. Reason: " + ex.Message)) e.Canceled = true End Try EndIf EndIf Next
ordersTable.Rows.Add(newRow) Me.GridSource.AcceptChanges()
Label1.Text = (Label1.Text + ("Order " _ + (newRow("OrderID") + " inserted"))) End Sub |
Note: You can also see the Accessing cells and rows section for more details about insert dependance from the Display/Visible/ReadOnly properties of grid columns.
Setting predefined values for different column editors
You can use the API for controlling automatic operations to achieve your goal. To set default values for GridBoundColumn/GridDropDownColumn/GridCheckBoxColumn/etc. field you can create ListDictionary object and set these preset values using the columns UniqueNames as keys.
For GridTemplateColumn fields, make sure that you specify the field to which you bind the control inside the template column as key for the dictionary object (passed to the InsertItem(newValues) method).
Below is a sample demonstration:
| ASPX/ASCX |
Copy Code |
|
<rad:RadGrid ID="RadGrid2" runat="server"> <MasterTableView Width="100%" CommandItemDisplay="Top" DataSourceID="AccessDataSource1" AutoGenerateColumns="False"> <Columns> <rad:GridTemplateColumn HeaderText="Check/Uncheck" UniqueName="BoolColumn"> <EditItemTemplate> <asp:CheckBox ID="chkBoxEdit" runat="server" Checked='<%# Bind("Bool") %>' /> </EditItemTemplate> <ItemTemplate> <asp:CheckBox ID="chkBoxDefault" runat="server" Checked='<%# Eval("Bool") %>' /> </ItemTemplate> </rad:GridTemplateColumn> <rad:GridBoundColumn DataField="CompanyName" HeaderText="CompanyName" UniqueName= "CompanyName"> </rad:GridBoundColumn> <rad:GridBoundColumn DataField="ContactName" HeaderText="ContactName" UniqueName= "ContactName"> </rad:GridBoundColumn> <rad:GridTemplateColumn UniqueName="CountryColumn" DataField="Country"> <ItemTemplate> <asp:Label ID="Label1" runat="server" Text='<%# Eval("Country") %>'></asp:Label> </ItemTemplate> <EditItemTemplate> ContactTitle: <asp:DropDownList ID="ddList1" runat="server" DataTextField="Country" DataValueField="Country" DataSource='<%# LoadCountryNames() %>' SelectedValue='<%# Bind("Country") %>'></asp:DropDownList> </EditItemTemplate> </rad:GridTemplateColumn> <rad:GridEditCommandColumn UniqueName="EditCommandColumn"> </rad:GridEditCommandColumn> </Columns> </MasterTableView> </rad:RadGrid> <asp:AccessDataSource ID="AccessDataSource1" DataFile="~/Grid/Data/Access/Nwind.mdb" SelectCommand="SELECT TOP 10 CompanyName, ContactName, ContactTitle FROM Customers" runat="server"></asp:AccessDataSource> |
And in the code-behind:
| VB.NET |
Copy Code |
|
Protected Sub RadGrid1_ItemCommand(ByVal source As Object, ByVal e As Telerik.WebControls.GridCommandEventArgs) Handles RadGrid2.ItemCommand If (e.CommandName = RadGrid.InitInsertCommandName) Then e.Canceled = True
Dim newValues As System.Collections.Specialized.ListDictionary = New System.Collections.Specialized.ListDictionary() newValues("ContactName") = "default contact name" newValues("CompanyName") = " default company name"
newValues("Country") = "Germany" newValues("Bool") = False
e.Item.OwnerTableView.InsertItem(newValues) End If End Sub |
| C# |
Copy Code |
|
protected void RadGrid1_ItemCommand(object source, Telerik.WebControls.GridCommandEventArgs e) { if (e.CommandName == RadGrid.InitInsertCommandName) { // cancel the default operation e.Canceled = true;
//Prepare an IDictionary with the predefined values System.Collections.Specialized.ListDictionary newValues = new System.Collections.Specialized.ListDictionary(); newValues["ContactName"] = "default contact name"; newValues["CompanyName"] = " default company name";
//set default value for the dropdown list inside the EditItemTemplate newValues["Country"] = "Germany";
//set default checked state for the checkbox inside the EditItemTemplate newValues["Bool"] = false;
//Insert the item and rebind e.Item.OwnerTableView.InsertItem(newValues);
} } |
The other option is to set AppendDataBoundItems="true" for the dropdown list (residing in edit template of template column) and add default empty item in the dropdown control to avoid exception generation on initial insert:
| ASPX/ASCX |
Copy Code |
|
<rad:GridTemplateColumn> <ItemTemplate> <%# Eval("ProductID") %> </ItemTemplate> <EditItemTemplate> <asp:DropDownList ID="DropDownList1" AppendDataBoundItems="true" DataSourceID="AccessDataSource2" DataTextField="ProductID" DataValueField="ProductID" SelectedValue='<%# Bind("ProductID") %>' runat="server"> <asp:ListItem Text="" Value="" /> </asp:DropDownList> </EditItemTemplate> </rad:GridTemplateColumn> |
This is a codeless approach, however have in mind that this empty option will be displayed in the dropdown editor of an existing edited grid row as well.