How to: Allow Users to Edit Items in DataList Web Server Controls

You can allow users to edit individual items in the DataList Web server control. When an individual item is set to edit mode, the values that can be changed are usually displayed in text boxes or other controls in which users can make their changes.

To allow users to edit items in a DataList control

  1. Set the DataList control's DataKeyField property to the name of the field in the data that contains the primary key.

  2. Create an ItemTemplate (and, if you are using it, an AlternatingItemTemplate), and then add a Button Web server control to it. Set the CommandName property for this button to edit.

    Note

    You can use a LinkButton or an ImageButton control in any step that calls for a Button Web server control.

  3. Create an EditItemTemplate for the DataList control that includes the following:

    • Controls for all of the values that users can change. For example, include TextBox controls for all character and numeric data. Use the declarative Eval method to specify which field each control is bound to, as in this example:

      Security noteSecurity Note:

      This example has a text box that accepts user input, which is a potential security threat. By default, ASP.NET Web pages validate that user input does not include script or HTML elements. For more information, see Script Exploits Overview.

      <asp:TextBox ID="TextBox1" 
        runat="server" 
        Text='<%# Eval("ProductName") %>' />
      
    • A Button control with its Text property set to "Update" and its CommandName property set to update (case-sensitive).

    • A Button control with its Text property set to "Cancel" and its CommandName property set to cancel.

      The Update button will allow users to specify that they are finished editing and will save any changes. The Cancel button will allow them to quit editing without saving changes.

  4. Write code to perform the following tasks:

    • Handle the DataList control's EditCommand event that sets the DataList control's EditItemIndex property to the index value of the item to put into edit mode. The index of the item that the user clicked is available via the Item object's ItemIndex property. Then call the control's DataBind method.

    • Handle the DataList control's CancelCommand event that sets the DataList control's EditItemIndex property to -1 and then calls the control's DataBind method.

    • Handle the DataList control's UpdateCommand event. In the code, extract the values from the controls in the current item and pass them to the data source control for an update operation. The exact code you use depends on the type of data source control that you are working with.

Example

The following code example shows an ASP.NET page that uses a DataList control and a SqlDataSource control to display information from the Categories table in the Northwind database. Users can edit the items.

Security noteSecurity Note:

This example has a text box that accepts user input, which is a potential security threat. By default, ASP.NET Web pages validate that user input does not include script or HTML elements. For more information, see Script Exploits Overview.

<%@ Page Language="VB" %>

<script runat="server">
Protected Sub DataList1_EditCommand(ByVal source As Object, _
        ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs)
    DataList1.EditItemIndex = e.Item.ItemIndex
    DataList1.DataBind()
End Sub

Protected Sub DataList1_CancelCommand(ByVal source As Object, _
        ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs)
    DataList1.EditItemIndex = -1
    DataList1.DataBind()
End Sub

Protected Sub DataList1_UpdateCommand(ByVal source As Object, _
        ByVal e As System.Web.UI.WebControls.DataListCommandEventArgs)
    Dim categoryID As String = _
        DataList1.DataKeys(e.Item.ItemIndex).ToString()
    Dim categoryName As TextBox = _
        CType(e.Item.FindControl("textCategoryName"), TextBox)
    Dim description As TextBox = _
        CType(e.Item.FindControl("textDescription"), TextBox)

    SqlDataSource1.UpdateParameters("original_CategoryID"). _
        DefaultValue = categoryID
    SqlDataSource1.UpdateParameters("categoryName"). _
        DefaultValue = categoryName.Text
    SqlDataSource1.UpdateParameters("Description"). _
        DefaultValue = description.Text
    SqlDataSource1.Update()
    DataList1.EditItemIndex = -1
    DataList1.DataBind()
End Sub
</script>

<html>
<head runat="server"></head>
<body>
  <form id="form1" runat="server">
    <div>
        <br />
        <asp:DataList runat="server" 
            DataKeyField="CategoryID" 
            DataSourceID="SqlDataSource1" ID="DataList1"
            OnEditCommand="DataList1_EditCommand" 
            OnCancelCommand="DataList1_CancelCommand" 
            OnUpdateCommand="DataList1_UpdateCommand">
            <EditItemTemplate>
                ID: <asp:Label ID="Label1" runat="server" 
                         Text='<%# Eval("CategoryID") %>'>
                    </asp:Label>
                <br />
                Name: <asp:TextBox ID="textCategoryName" runat="server" 
                         Text='<%# Eval("CategoryName") %>'>
                      </asp:TextBox>
                <br />
                Description: <asp:TextBox ID="textDescription" 
                                 runat="server" 
                        Text='<%# Eval("Description") %>'>
                     </asp:TextBox>
                <br />
                <asp:LinkButton ID="LinkButton1" runat="server" 
                    CommandName="update" >
                    Save
                </asp:LinkButton>
                &nbsp;
                <asp:LinkButton ID="LinkButton2" runat="server">
                    CommandName="cancel" 
                    Cancel
                </asp:LinkButton>
            </EditItemTemplate>
            <ItemTemplate>
                CategoryID:
                <asp:Label ID="CategoryIDLabel" runat="server" 
                    Text='<%# Eval("CategoryID") %>'>
                </asp:Label>
                <br />
                CategoryName:
                <asp:Label ID="CategoryNameLabel" runat="server"
                     Text='<%# Eval("CategoryName") %>'>
                </asp:Label>
                <br />
                Description:
                <asp:Label ID="DescriptionLabel" runat="server" 
                    Text='<%# Eval("Description") %>'>
                </asp:Label>
                <br />
                <asp:LinkButton runat="server" ID="LinkButton1" 
                    CommandName="edit" >
                    Edit
                </asp:LinkButton><br />
            </ItemTemplate>
        </asp:DataList>

        <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
              ConnectionString=
                  "<%$ ConnectionStrings:NorthwindConnectionString %>"
            SelectCommand="SELECT [CategoryID], [CategoryName], 
                 [Description] FROM [Categories]"
            UpdateCommand="UPDATE [Categories] SET [CategoryName] = 
                 @CategoryName, [Description] = @Description 
                 WHERE [CategoryID] = @original_CategoryID">
            <UpdateParameters>
              <asp:Parameter Name="CategoryName" Type="String" />
              <asp:Parameter Name="Description" Type="String" />
              <asp:Parameter Name="original_CategoryID" Type="Int32" />
            </UpdateParameters>
        </asp:SqlDataSource>
    </div>
  </form>
</body>
</html>
<%@ Page Language="C#" %>
<script runat="server">
protected void DataList1_EditCommand(object source, 
    DataListCommandEventArgs e)
{
    DataList1.EditItemIndex = e.Item.ItemIndex;
    DataList1.DataBind();
}

protected void DataList1_CancelCommand(object source, 
    DataListCommandEventArgs e)
{
    DataList1.EditItemIndex = -1;
    DataList1.DataBind();
}

protected void DataList1_UpdateCommand(object source, 
    DataListCommandEventArgs e)
{
    String categoryID = 
         DataList1.DataKeys[e.Item.ItemIndex].ToString();
    String categoryName = 
         ((TextBox)e.Item.FindControl("textCategoryName")).Text;
    String description = 
         ((TextBox) e.Item.FindControl("textDescription")).Text;

    SqlDataSource1.UpdateParameters["original_CategoryID"].DefaultValue 
        = categoryID;
    SqlDataSource1.UpdateParameters["categoryName"].DefaultValue 
        = categoryName;
    SqlDataSource1.UpdateParameters["Description"].DefaultValue 
        = description;
    SqlDataSource1.Update();

    DataList1.EditItemIndex = -1;
    DataList1.DataBind();
}
</script>
<html>
<head runat="server"></head>
<body>
  <form id="form1" runat="server">
    <div>
        <br />
        <asp:DataList runat="server" 
            DataKeyField="CategoryID" 
            DataSourceID="SqlDataSource1" ID="DataList1"
            OnEditCommand="DataList1_EditCommand" 
            OnCancelCommand="DataList1_CancelCommand" 
            OnUpdateCommand="DataList1_UpdateCommand">
            <EditItemTemplate>
                ID: <asp:Label ID="Label1" runat="server" 
                         Text='<%# Eval("CategoryID") %>'>
                    </asp:Label>
                <br />
                Name: <asp:TextBox ID="textCategoryName" runat="server" 
                         Text='<%# Eval("CategoryName") %>'>
                      </asp:TextBox>
                <br />
                Description: <asp:TextBox ID="textDescription" 
                                 runat="server" 
                        Text='<%# Eval("Description") %>'>
                     </asp:TextBox>
                <br />
                <asp:LinkButton ID="LinkButton1" runat="server" 
                    CommandName="update" >
                    Save
                </asp:LinkButton>
                &nbsp;
                <asp:LinkButton ID="LinkButton2" runat="server">
                    CommandName="cancel" 
                    Cancel
                </asp:LinkButton>
            </EditItemTemplate>
            <ItemTemplate>
                CategoryID:
                <asp:Label ID="CategoryIDLabel" runat="server" 
                    Text='<%# Eval("CategoryID") %>'>
                </asp:Label>
                <br />
                CategoryName:
                <asp:Label ID="CategoryNameLabel" runat="server"
                     Text='<%# Eval("CategoryName") %>'>
                </asp:Label>
                <br />
                Description:
                <asp:Label ID="DescriptionLabel" runat="server" 
                    Text='<%# Eval("Description") %>'>
                </asp:Label>
                <br />
                <asp:LinkButton runat="server" ID="LinkButton1" 
                    CommandName="edit" >
                    Edit
                </asp:LinkButton><br />
            </ItemTemplate>
        </asp:DataList>

        <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
              ConnectionString=
                 "<%$ ConnectionStrings:NorthwindConnectionString %>"
            SelectCommand="SELECT [CategoryID], [CategoryName], 
                 [Description] FROM [Categories]"
            UpdateCommand="UPDATE [Categories] SET [CategoryName] = 
                 @CategoryName, [Description] = @Description 
                 WHERE [CategoryID] = @original_CategoryID">
            <UpdateParameters>
               <asp:Parameter Name="CategoryName" Type="String" />
              <asp:Parameter Name="Description" Type="String" />
              <asp:Parameter Name="original_CategoryID" Type="Int32" />
            </UpdateParameters>
        </asp:SqlDataSource>
    </div>
  </form>
</body>
</html>

To update data, you need the primary key of the record that is being updated. You can get that value from the DataKeyField property, which contains an array of keys.

To get the value of a specific control in the item, use the FindControl method of the Item event-argument object.

The values that you set in the SqlDataSource1.UpdateParameters dictionary must match the names that you set in the UpdateParameters element.

Compiling the Code

The code requires that you have a connection string named NorthwindConnectionString. The database you connect to is assumed to have a table named Categories with the fields CategoryID, CategoryName, and Description.

The account under which the page connects to the database must have permission to update the Category table.

Robust Programming

The code in the example does not perform the following tasks that you would normally do in a production environment:

  • The code does not include error checking to be sure that the FindControl method returns a valid control. For more robust code, make sure that the value returned by the FindControl method is not a null reference (Nothing in Visual Basic).

  • The code does not check whether the update was successful.

Security

User input in a Web Forms page can include potentially malicious client script. By default, the Web Forms page validates that user input does not include script or HTML elements. For more information, see Script Exploits Overview.

See Also

Concepts

Modifying Data using the SqlDataSource Control

Using Parameters with the SqlDataSource Control

Reference

DataList Web Server Control Overview