This is a migrated thread and some comments may be shown as answers.

Edit/update grid without javascript or datasource

7 Answers 297 Views
Grid
This is a migrated thread and some comments may be shown as answers.
PAYDAY
Top achievements
Rank 1
PAYDAY asked on 08 Jan 2009, 10:10 PM
Hi all,

Users would like to have the ability to click on a row in the datagrid and have it go into edit mode. Then, tab through each of the cells changing data, then when they leave the row, save the data. I'm binding using the Need_DataSource event so I'm NOT using a data source contol. I can handle all of the saving.

I don't want to use Javascript. I'd rather fire a command event when the click the row and fire a command event when the leave the row. (BUT HOW?) I'll then put the row into edit mode.

NOTE: I will be using controls in different cells like comboboxes. I can create these manually in the grid and just hide them if I don't want them to displayed to the user. (if you see in my code, I have a ConfigureGridColumn() method for doing this - and that part already works).

How do I:
- Fire an event when the click the row and when they leave the row without javascript? (can I use the ItemCommand?)
- Add markup for a ComboBox, MaskedEdit, NumericText, etc. to cells

Here's the markup I have so far:

<telerik:RadGrid ID="EditableGrid" runat="server" Skin="Gray"
    GridLines="None" OnNeedDataSource="EditableGrid_NeedDataSource"
    AllowPaging="True" AllowSorting="True"
    OnItemCommand="EditableGrid_ItemCommand">
    <PagerStyle Mode="NextPrevAndNumeric" />
    <MasterTableView CommandItemDisplay="Top" EditMode="InPlace" >
        <RowIndicatorColumn>
            <HeaderStyle Width="20px"></HeaderStyle>
        </RowIndicatorColumn>
        <ExpandCollapseColumn>
            <HeaderStyle Width="20px"></HeaderStyle>
        </ExpandCollapseColumn>       
    </MasterTableView>
    <FilterMenu EnableTheming="True">
        <CollapseAnimation Type="OutQuint" Duration="200"></CollapseAnimation>
    </FilterMenu>
</telerik:RadGrid>


Here's my code:
    protected void EditableGrid_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
    {
        EditableGrid.DataSource = GetMyData();
        EditableGrid.MasterTableView.DataKeyNames = new string[] {  "MYDataID" };
    }
    protected void EditableGrid_ColumnCreated(object sender, Telerik.Web.UI.GridColumnCreatedEventArgs e)
    {
        //set column attributes - show/hide/width etc..
        ConfigureGridColumn(e.Column);
    }

    protected void EditableGrid_ItemCommand(object source, GridCommandEventArgs e)
    {
        switch (e.CommandName.ToLower())
        {
            case "edit":
                e.Item.Edit = true;
                break;
            case "update":
                UpdateItem(e.Item);
                break;
            case "cancel":
                e.Item.Edit = false;
                break;
        }
    }

    private void UpdateItem(GridItem gridItem)
    {
        DataTable dt = new DataTable();
        
        //create an empty data table with all the columns from the grid
        foreach (GridColumn column in EditableGrid.MasterTableView.RenderColumns)
        {
            dt.Columns.Add(new DataColumn(column.UniqueName));
        }

        DataRow dr = dt.NewRow();
        //add data from grid to new row in data table
        foreach (GridColumn column in EditableGrid.MasterTableView.RenderColumns)
        {
            dr[column.UniqueName] = ((gridItem as GridEditableItem).EditManager.GetColumnEditor(column.UniqueName) as GridTextColumnEditor).Text;
            //for control within cell Does this work???
            //RadComboBox control = (e.Item as GridEditableItem)["UNIQUE NAME"].Controls[0] as RadComboBox;
        }

        //My Custom entity to save data
        MyEntity entity = MyEntity.DataBind(dr);
        entity.SaveData();    
    }



7 Answers, 1 is accepted

Sort by
0
PAYDAY
Top achievements
Rank 1
answered on 09 Jan 2009, 06:24 PM
I've revised my HTML markup to this. Notice I'm adding the columns manually:

<telerik:RadGrid ID="EditableGrid" runat="server" Width="400px" OnItemCreated="EditableGrid_ItemCreated"
    OnNeedDataSource="EditableGrid_NeedDataSource">
    <MasterTableView AutoGenerateColumns="false" EditMode="InPlace">
        <Columns>
            <telerik:GridEditCommandColumn UniqueName="EditCommandColumn" />

            <telerik:GridTemplateColumn UniqueName="TemplateColumn" HeaderText="Checkbox Column">
                <ItemTemplate>
                    <asp:Panel ID="Panel1" runat="server">
                        <asp:CheckBox ID="CheckBox1" runat="server" />
                    </asp:Panel>
                </ItemTemplate>
            </telerik:GridTemplateColumn>
            <telerik:GridDropDownColumn UniqueName="DropDown" DataField="DropDown" HeaderText="DropDown List Column" />
            <telerik:GridBoundColumn UniqueName="Text1" DataField="Text1" HeaderText="Text Column" />
        </Columns>
    </MasterTableView>
</telerik:RadGrid>

Here's my code behind.

    protected void EditableGrid_NeedDataSource(object source, GridNeedDataSourceEventArgs e)
    {
        EditableGrid.DataSource = MyEntity.GetList();
        EditableGrid.MasterTableView.DataKeyNames = new string[] { "EntityID" };
    }

    protected void EditableGrid_ItemCreated(object sender, GridItemEventArgs e)
    {
        if (e.Item is GridEditableItem && e.Item.IsInEditMode)
        {
            AddFundList((GridEditableItem)e.Item);
        }
    }

    private void AddFundList(GridEditableItem gridItem)
    {
        //the dropdown list will be the first control in the Controls collection of the corresponding cell
        RadComboBox list = (RadComboBox)gridItem["DropDown"].Controls[0];
        list.DataTextField = "DDLText"
        list.DataValueField = "DDLValue"
        list.DataSource = MyEntity.GetDDLList();
        list.DataBind();
    }


The problem is, the data doesn't display in the dropdown list for non-edit or edit modes.



0
Rosen
Telerik team
answered on 12 Jan 2009, 12:19 PM
Hello Kevin,

The cause for RadComboBox not been populated is the way it is databound. As you may know changes set to GridDropDown column's datasource during the ItemCreated event are overridden when the column is databound.  In order to databind the RadComboBox in the suggested way you may consider using a GridTemplateColumn with RadComboBox in its EditItemTemplate instead RadGrid's GridDropDownColumn.

Best wishes,
Rosen
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
PAYDAY
Top achievements
Rank 1
answered on 12 Jan 2009, 01:08 PM
OKAY!!!  I've got this working. The only thing I need now is to add code to switch to edit mode when I click on the row. I also need code to update when I tab off the row (blur???). REMEMBER, I'm trying not to use Javascript if possible but if I have to use javascript, I'd like it to fire the Update (or Insert) command. Help?

HTML:
<telerik:RadGrid ID="EditableGrid" runat="server" Skin="Gray"
    AutoGenerateColumns="false"
    AutoGenerateEditColumn="False"
    GridLines="None"
    OnNeedDataSource="EditableGrid_NeedDataSource"
    OnItemCreated="EditableGrid_ItemCreated"
    OnItemDataBound="EditableGrid_ItemDataBound"
    OnItemCommand="EditableGrid_ItemCommand"
    AllowPaging="True" AllowSorting="True" >
    <PagerStyle Mode="NextPrevAndNumeric" />
    <MasterTableView CommandItemDisplay="Top" EditMode="InPlace" ExpandCollapseColumn-Display="false">
        <RowIndicatorColumn>
            <HeaderStyle Width="20px"></HeaderStyle>
        </RowIndicatorColumn>
        <ExpandCollapseColumn>
            <HeaderStyle Width="20px"></HeaderStyle>
        </ExpandCollapseColumn>
        <Columns>
            <telerik:GridEditCommandColumn UniqueName="EditCommandColumn" />
            
            <telerik:GridTemplateColumn UniqueName="TemplateColumn" HeaderText="ComboBox Column">
                <ItemTemplate>
                    <asp:Label ID="Field1" runat="server" Text='<%#Eval("Field1") %>'></asp:Label>
                </ItemTemplate>
                <EditItemTemplate>
                    <telerik:RadComboBox ID="Field1" runat="server">
                    </telerik:RadComboBox>
                </EditItemTemplate>
            </telerik:GridTemplateColumn>

            <telerik:GridTemplateColumn UniqueName="TemplateColumn" HeaderText="TextBox Column">
                <ItemTemplate>
                    <asp:Label ID="Field2" runat="server" Text='<%#Eval("Field2") %>'></asp:Label>
                </ItemTemplate>
                <EditItemTemplate>
                    <telerik:RadTextBox ID="Field2" runat="server">
                    </telerik:RadTextBox>
                </EditItemTemplate>
            </telerik:GridTemplateColumn>           
        </Columns>
    </MasterTableView>
    <FilterMenu EnableTheming="True">
        <CollapseAnimation Type="OutQuint" Duration="200"></CollapseAnimation>
    </FilterMenu>
</telerik:RadGrid>


CODE:
    #region Methods
    private void PopulateField1List(GridEditableItem item)
    {
        //the dropdown list will be the first control in the Controls collection of the corresponding cell
        RadComboBox list = (RadComboBox)item["TemplateColumn"].FindControl("Field1");
        list.DataTextField = MyEntity.DBFieldName.Field1.ToString();
        list.DataValueField = MyEntity.DBFieldName.Field1.ToString();
        list.DataSource = MyEntity.GetList();
        list.DataBind();
    }

    private void Populate(GridEditableItem item)
    {
        if (item.ItemIndex < 0)
        {
            //inserting item so do not populate
            return;
        }

           //Get the entity data from the database using the uniqueKey from the row selected
        string uniqueKey = item.OwnerTableView.DataKeyValues[item.ItemIndex][MyEntity.DBFieldName.MyEntityID.ToString()].ToString();
        MyEntity entity = MyEntity.GetByKey(uniqueKey);
        
        //Custom method that uses reflection to populate the item selected
        PopulateUIFromEntity(entity, item["TemplateColumn"]);
    }

    /// <summary>
    /// Method to update the currently selected grid item
    /// </summary>
    /// <param name="item"></param>
    /// <returns>True=success</returns>
    private bool UpdateItem(GridDataItem item)
    {
           //Get the entity data from the database using the uniqueKey from the row selected
        string uniqueKey = item.OwnerTableView.DataKeyValues[item.ItemIndex][MyEntity.DBFieldName.MyEntityID.ToString()].ToString();
        MyEntity entity = MyEntity.GetByKey(uniqueKey);

                //Custom method that uses reflection to populate entity from the item selected
        PopulateEntityFromUI(entity, item["TemplateColumn"]);
        
        //saves the data
        return entity.SaveData();
    }

    /// <summary>
    /// Method to insert new grid item
    /// </summary>
    /// <param name="item"></param>
    /// <returns>True=success</returns>
    private bool InsertItem(GridDataItem item)
    {
        MyEntity entity = new MyEntity();
        
        //Custom method that uses reflection to populate entity from the item selected
        PopulateEntityFromUI(entity, item["TemplateColumn"]);
        return entity.SaveData();
    }
    #endregion

    #region Form Events
    protected void EditableGrid_NeedDataSource(object source, Telerik.Web.UI.GridNeedDataSourceEventArgs e)
    {
        EditableGrid.DataSource = MyEntity.GetData();
        EditableGrid.MasterTableView.DataKeyNames = new string[] { MyEntity.DBFieldName.MyEntityID.ToString() };
    }

    protected void EditableGrid_ItemCreated(object sender, GridItemEventArgs e)
    {
        if (e.Item is GridEditableItem && e.Item.IsInEditMode)
        {
            PopulateField1List((GridEditableItem)e.Item);
        }
    }

    protected void EditableGrid_ItemDataBound(object sender, GridItemEventArgs e)
    {
        if (e.Item is GridEditableItem && e.Item.IsInEditMode)
        {
            Populate((GridEditableItem)e.Item);
        }
    }

    protected void EditableGrid_ItemCommand(object source, GridCommandEventArgs e)
    {
        switch (e.CommandName.ToLower())
        {
            case "initinsert":
                //add new
                ControlBase.EditSuccessful = false;
                break;
            case "performinsert":
                e.Canceled = !InsertItem((GridDataItem)e.Item);
                break;
            case "edit":
                ControlBase.EditSuccessful = false;
                break;
            case "update":
                e.Canceled = !UpdateItem((GridDataItem)e.Item);
                
                break;
            case "cancel":
                break;
        }
    }

    #endregion


0
Rosen
Telerik team
answered on 14 Jan 2009, 01:05 PM
Hello Kevin,

Please refer to this online demo which demonstrates how to achieve similar to the requested functionality.

Sincerely yours,
Rosen
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
PAYDAY
Top achievements
Rank 1
answered on 14 Jan 2009, 02:47 PM
Thanks for your response. I reviewed this prior to posting - it is close but not quite what I need. For example, if you edit a row then click off the grid, no update confirmation happens. This only occurs when you click another row.
0
Rosen
Telerik team
answered on 16 Jan 2009, 01:36 PM
Hi Kevin,

In order to achieve the requested functionality you may hook to document's click event and check if the current clicked element is outside of RadGrid control and in this case prompt for conformation to save the record. Similar to the following:

            function pageLoad()  
            {  
                $addHandler(document"click", document_click)  
            }  
              
            function document_click(e)  
            {                 
                if(editedRow && hasChanges &&   
                    !$telerik.isDescendant($find("<%=RadGrid1.ClientID %>").get_element(), Telerik.Web.UI.Grid.GetCurrentElement(e))                  
                )  
                {     
                    if(confirm("Update changes?"))  
                    {  
                        hasChanges = false;  
                        $find("<%= RadGrid1.MasterTableView.ClientID %>").updateItem(editedRow);  
                    }  
                }  
            } 

Please give it a try and let us know if this helps.

Kind regards,
Rosen
the Telerik team

Check out Telerik Trainer, the state of the art learning tool for Telerik products.
0
PAYDAY
Top achievements
Rank 1
answered on 20 Jan 2009, 12:47 PM
Cool - I'll give that a try.
Tags
Grid
Asked by
PAYDAY
Top achievements
Rank 1
Answers by
PAYDAY
Top achievements
Rank 1
Rosen
Telerik team
Share this question
or