Click here to Skip to main content
Click here to Skip to main content

Insert a new record using ListView with a GridView-like interface

, 20 Nov 2009
Rate this:
Please Sign up or sign in to vote.
This article talks about inserting a new record in a ListView which has a GridView as a user interface. It also explains inline edit and delete functionality.

Introduction

Inserting a new record in a database table using a GridView has never been easy, or at least is not an out-of-the-box feature.

For this purpose, the ListView has been introduced in which inserting a new record is an out-of-the-box feature. We’ll see how to use the ListView in place of the GridView to insert a new record, making the UI look just like a GridView. This is a basic article that helps a beginner to understand the insert, edit, and delete functionalities of the ListView control.

The ListView control is a new data presentation control introduced in .NET 3.5 to cater to the complex business needs of displaying data. Though ListView is provided with a huge number of properties that provide flexibility in behaviour and appearance, we are not dealing with those in this article.

On click of the Add button:

On click of the Save button with invalid entries:

Create Data Source

I am using the SqlDataSource control to handle the insert, update, and delete functionality with inline SQL queries. You can choose to use ObjectDataSource with DataSets and Stored Procedures to do the same for a better tiered architecture.

Add a ListView

In the code below, we have used four templates: ItemTemplate, InsertItemTemplate, EditItemTemplate, and EmptyDataTemplate after the mandatory LayoutTemplate.

LayoutTemplate

LayoutTemplate is the template for the rows parent table. Basically, this template is used to create the main (or root) layout for the control. The template will obviously have a <table> element because this example renders data to an HTML table. However, there is no restriction. The LayoutTemplate and ItemTemplate should be in sync. This is because the LayoutTemplate contains a special placeholder item that is replaced with the HTML markup generated from ItemTemplate. So in this example, the LayoutTemplate contains an HTML table with two child rows, one that defines the header cells, and another that is a placeholder for the databound rows. When the ListView renders, the placeholder is replaced with what is generated from the ItemTemplate being bound to each of the items in the data source.

<LayoutTemplate>
    <table id="tblCotnacts" runat="server" 
                class="edit-table-listview">
        <tr>
            <th>Contact Type</th>
            <th>Title</th>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Phone</th>
            <th></th>
        </tr>
        <tr runat="server" id="itemPlaceholder"></tr>
    </table>
</LayoutTemplate>

ItemTemplate

ItemTemplate is to render all the rows by running through each of these rows to generate the read-only cells for the data item portion. This is similar to the Columns collection of the GridView. This is where you will use the data binding syntax to bind the values of the attributes from your data source to their corresponding UI elements.

<ItemTemplate>
    <tr>
        <td><%#Eval("ContactType")%></td>
        <td><%#Eval("Title")%></td>
        <td><%#Eval("FirstName")%></td>
        <td><%#Eval("LastName")%></td>
        <td><%#Eval("Phone")%></td>
        <td>
            <asp:ImageButton ID="imgbEdit" runat="server" 
               CommandName="Edit" Text="Edit" 
               ImageUrl="~/Images/edit_icon_mono.gif" />
            <asp:ImageButton ID="imgbDelete" runat="server" 
               CommandName="Delete" Text="Delete" 
               ImageUrl="~/Images/delete_icon_mono.gif" 
               OnClientClick=
                 "return confirm('Are you sure you want to delete this contact?');" 
               ToolTip="Delete"/>
        </td>
    </tr>
</ItemTemplate>

If you observe the code, OnClientClick has been used for the delete image button. This is to pop up a confirmation box when the user tries to delete a row.

InsertItemTemplate

InsertItemTemplate is to have the ASP.NET controls which will be rendered when the Insert command is passed. Add controls and bind them to the data in the data source. Also, the validation controls can be added to all the input controls. Add two buttons to insert and cancel the user input. Set the causesvalidation property of the Insert button to true and that of the Cancel button to false.

<InsertItemTemplate>
    <tr>
        <td>
            <asp:DropDownList ID="ddlContactTypeInsert" 
                    runat="server" DataSourceID="sqlDsContactType" 
                    DataTextField="ContactType" 
                    DataValueField="ContactTypeID" 
                    CssClass="edit-table-input" 
                    width="215px" AppendDataBoundItems="true">
                <asp:ListItem Text="" Value=""></asp:ListItem>
            </asp:DropDownList>
            <asp:RequiredFieldValidator ID="rfvSchemeSalaryTypeInsert" 
                runat="server" ControlToValidate="ddlContactTypeInsert" 
                ErrorMessage="Missing contact type" 
                SetFocusOnError="true" 
                ValidationGroup="vgrpSaveContact" Display="None">
            </asp:RequiredFieldValidator>
        </td>
        <td>
            <asp:TextBox ID="txtTitleInsert" 
               runat="server" Text='<%# Bind("Title") %>' 
               width="48px"/>
        </td>
        <td>
            <asp:TextBox ID="txtFirstNameInsert" runat="server" 
               Text='<%# Bind("FirstName") %>' width="78px"/>
            <asp:RequiredFieldValidator ID="rfvFirstNameInsert" 
               runat="server" ControlToValidate="txtFirstNameInsert" 
               ErrorMessage="Missing first name" SetFocusOnError="true" 
               ValidationGroup="vgrpSaveContact" Display="None">
            </asp:RequiredFieldValidator>
        </td>
        <td>
            <asp:TextBox ID="txtLastNameInsert" runat="server" 
                Text='<%# Bind("LastName") %>' width="78px"/>
            <asp:RequiredFieldValidator ID="rfvLastNameInsert" 
               runat="server" ControlToValidate="txtLastNameInsert" 
               ErrorMessage="Missing last name" SetFocusOnError="true" 
               ValidationGroup="vgrpSaveContact" Display="None">
            </asp:RequiredFieldValidator>
        </td>
        <td>
            <asp:TextBox ID="txtPhoneInsert" runat="server" 
                Text='<%# Bind("Phone") %>' width="113px"/>
            <asp:RequiredFieldValidator ID="rfvPhoneInsert" 
               runat="server" ControlToValidate="txtPhoneInsert" 
               ErrorMessage="Missing phone number" SetFocusOnError="true" 
               ValidationGroup="vgrpSaveContact" Display="None">
            </asp:RequiredFieldValidator>
        </td>
        <td>
            <asp:ImageButton ID="imgbInsert" runat="server" 
                 CommandName="Insert" Text="Insert" 
                 ImageUrl="~/Images/add_icon_mono.gif" 
                 ValidationGroup="vgrpSaveContact"/>
            <asp:ImageButton ID="imgbCancelInsert" runat="server" 
                 CommandName="Cancel" Text="Clear" 
                 ImageUrl="~/Images/undo_icon_mono.gif" 
                 onclick="CancelAddNew"/>
        </td>
    </tr>
</InsertItemTemplate>

Implement the image button’s Click event in the code-behind, as shown below:

Private Sub imgbNew_Click(ByVal sender As Object, _
            ByVal e As System.Web.UI.ImageClickEventArgs) Handles imgbNew.Click
    lvContacts.InsertItemPosition = InsertItemPosition.FirstItem
    imgbNew.Enabled = False
    ' cancels if any row is in edit mode
    lvContacts.EditIndex = -1
End Sub

Use the ListView’s ItemInserting event to send the selected value in the dropdown to the insert parameters:

Private Sub lvContacts_ItemInserting(ByVal sender As Object, _
         ByVal e As System.Web.UI.WebControls.ListViewInsertEventArgs) _
         Handles lvContacts.ItemInserting
    e.Values("ContactTypeID") = _
      TryCast(e.Item.FindControl("ddlContactTypeInsert"), DropDownList).SelectedValue
End Sub

Implement the CancelAddNew() function in the code-behind and call it from the Listview events ItemInserted (to close the insert row after the insert) and ItemEditing (to close the insert row when a row is clicked for edit):

Protected Sub CancelAddNew()
    lvContacts.InsertItemPosition = InsertItemPosition.None
    imgbNew.Enabled = True
End Sub

Private Sub lvContacts_ItemInserted(ByVal sender As Object, _
            ByVal e As System.Web.UI.WebControls.ListViewInsertedEventArgs) _
    Handles lvContacts.ItemInserted
    CancelAddNew()
End Sub

Private Sub lvContacts_ItemEditing(ByVal sender As Object, _
        ByVal e As System.Web.UI.WebControls.ListViewEditEventArgs) _
        Handles lvContacts.ItemEditing
    CancelAddNew()
End Sub

EditItemTemplate

EditItemTemplate is to have the ASP.NET controls which will be rendered when the Edit command is passed. Add controls and bind them to the data in the data source. Also, validation controls can be added to all the input controls. Add two buttons to save and cancel the user input. Set the causesvalidation property of the Save button to true and that of the Cancel button to false.

<EditItemTemplate>
    <tr>
        <td>
            <asp:DropDownList ID="ddlContactTypeEdit" runat="server" 
                 DataSourceID="sqlDsContactType" DataTextField="ContactType" 
                 DataValueField="ContactTypeID" 
                 CssClass="edit-table-input" 
                 width="215px" AppendDataBoundItems="true"
                 SelectedValue='<%# Bind("ContactTypeID") %>'>
               <asp:ListItem Text="" Value=""></asp:ListItem>
            </asp:DropDownList>
            <asp:RequiredFieldValidator ID="rfvSchemeSalaryTypeEdit" 
                runat="server" ControlToValidate="ddlContactTypeEdit" 
                ErrorMessage="Missing contact type" 
                SetFocusOnError="true" 
                ValidationGroup="vgrpSaveContact" Display="None">
           </asp:RequiredFieldValidator>
        </td>
        <td>
            <asp:TextBox ID="txtTitleEdit" runat="server" 
               Text='<%# Bind("Title") %>' width="48px"/>
        </td>
        <td>
            <asp:TextBox ID="txtFirstNameEdit" runat="server" 
                Text='<%# Bind("FirstName") %>' width="78px"/>
            <asp:RequiredFieldValidator ID="rfvFirstNameEdit" 
                runat="server" ControlToValidate="txtFirstNameEdit" 
                ErrorMessage="Missing first name" 
                SetFocusOnError="true" 
                ValidationGroup="vgrpSaveContact" Display="None">
            </asp:RequiredFieldValidator>
        </td>
        <td>
            <asp:TextBox ID="txtLastNameEdit" runat="server" 
               Text='<%# Bind("LastName") %>' width="78px"/>
            <asp:RequiredFieldValidator ID="rfvLastNameEdit" 
                runat="server" ControlToValidate="txtLastNameEdit" 
                ErrorMessage="Missing last name" SetFocusOnError="true" 
                ValidationGroup="vgrpSaveContact" Display="None">
            </asp:RequiredFieldValidator>
        </td>
        <td>
            <asp:TextBox ID="txtPhoneEdit" runat="server" 
               Text='<%# Bind("Phone") %>' width="113px"/>
            <asp:RequiredFieldValidator ID="rfvPhoneEdit" 
                runat="server" ControlToValidate="txtPhoneEdit" 
                ErrorMessage="Missing phone" SetFocusOnError="true" 
                ValidationGroup="vgrpSaveContact" Display="None">
           </asp:RequiredFieldValidator>
        </td>
        <td>
            <asp:ImageButton ID="imgbUpdate" runat="server" 
                CommandName="Update" Text="Update" 
                ImageUrl="~/Images/save_icon_mono.gif" 
                CausesValidation="true" 
                ValidationGroup="vgrpSaveContact"/>
            <asp:ImageButton ID="imgbCancel" runat="server" 
                CommandName="Cancel" Text="Cancel" 
                ImageUrl="~/Images/undo_icon_mono.gif" 
                CausesValidation="false"/>
        </td>
    </tr>
</EditItemTemplate>

EmptyDataTemplate

EmptyDataTemplate will be fired when there is no data returned by the data source. A custom message would suffice in this case.

<EmptyDataTemplate>
    <tr>
        <td>
            No data was returned.
        </td>
    </tr>
</EmptyDataTemplate>

On click of the Add button:

Validation

As we have added client side validators, we can choose to show the summary of the error messages using a ValidationSummary control. The validation summary can either be displayed on the screen or can be popped up as a message box.

Use the ValidationGroup attribute to all the validators to group them with the button that causes the validation. Styles can be used to generate a really nice UI for the validation summary.

<asp:ValidationSummary ID="vsumSaveContact" 
    runat="server" ValidationGroup="vgrpSaveContact" 
    EnableClientScript="true"       
    SkinID="valSummaryError" 
    DisplayMode="BulletList" 
    HeaderText="Please correct the below errors." />

Use the following CSS code to generate the validation summary as shown in the screenshots:

.validation-summary-errors 
{
    width: 300px;
    border-color: Red;
    border-style: solid;
    border-width: 1px;
    background-color:#FFFFF3;	
    margin: 5px 0px;
    padding-top: 5px;
    padding-left: 15px;	
    font-size: 8pt;    
    color: red;
}

.validation-summary-errors ul 
{
    list-style: disc inside;
    padding:5px;
    margin:2px;
}

If the summary is to be popped up, add the following attributes to the above validation summary:

ShowMessageBox="true" ShowSummary="false"

Colour Invalid Controls

Also, we have added JavaScript code to colour the invalid controls:

<script language="javascript" type="text/javascript">
   function ChangeColourOfInvalidControls()
   {
        try
        {        
            for (var i = 0; i < Page_Validators.length; i++)
            {
                var valdtr = Page_Validators[i];
                var ctrl = document.getElementById(valdtr.controltovalidate);
                if (ctrl != null && ctrl.style != null)
                {
                  if (!valdtr.isvalid)
                      ctrl.style.backgroundColor="#F3F781";
                  else
                      ctrl.style.backgroundColor = "";
                }
            }
        }
        catch(e)
        {
            //Page_Validators will be null on page load
        }
    }
</script>

Register this JavaScript method in the code-behind page by using RegisterOnSubmitStatement.

ClientScript.RegisterOnSubmitStatement(Me.Page.GetType(), _
   "ChangeColourOfInvalidControls", "ChangeColourOfInvalidControls();")

The JavaScript array Page_Validators is defined in the ASP.NET framework’s client-side scripts. If this JavaScript code generates any error, make sure to run the following command in the Visual Studio command prompt:

aspnet_regiis -c

This would install the client-side scripts for ASP.NET, such as client-side validation scripts, to the aspnet_client subdirectory of each Internet Information Services (IIS) site directory.

How to Use the Code

The complete code has been provided as a downloadable. To use this, all you need to do is to have the AdventureWorks database installed and with a little bit of tweaks.

  • I am using the Person.Contacts table in this example after amending some of the columns to allow nulls.
  • I have added a new column ContactTypeID as a foreign key to the table Person.ContactType to have a dropdown as one of the controls while inline editing.
  • I have used inline SQL queries in the select, update, insert, and delete commands of the data source just to make the code work. However, this is not recommended, as the best way to do is to have Stored Procedures in a multi-tier application.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Ramakrishna Pillai
Web Developer
United Kingdom United Kingdom
No Biography provided

Comments and Discussions

 
GeneralThank you Pinmembersharp_k12-Jul-12 10:35 
QuestionExcellent article PinmemberDanExact3-May-12 3:49 
GeneralMy vote of 4 PinmemberJohn Nollet24-Jan-11 2:27 
Generalpretty bad article!! PinmemberNutsAboutVB.Net11-Dec-09 22:15 
GeneralMy vote of 1 PinmemberNutsAboutVB.Net11-Dec-09 22:14 
GeneralMy vote of 1 PinmemberNutsAboutVB.Net11-Dec-09 22:14 
GeneralTerrible Article & Example filled with Typos! [modified] PinmemberTV Mogul26-Nov-09 3:46 
GeneralRe: Terrible Article & Example filled with Typos! PinmemberRamakrishna Pillai27-Nov-09 6:22 
GeneralYou are still WRONG and your sample is terrible! PinmemberTV Mogul27-Nov-09 7:34 
GeneralItemInserting event PinmemberRichard Deeming24-Nov-09 7:20 
GeneralRe: ItemInserting event PinmemberRamakrishna Pillai26-Nov-09 2:26 
GeneralNice PinmemberMuneeb R. Baig23-Nov-09 20:17 
GeneralRe: Nice PinmemberRamakrishna Pillai26-Nov-09 2:25 
Questioncool but how about paging sorting and filtering options? PinmemberMohamed Abdullah 8223-Nov-09 19:58 
AnswerRe: cool but how about paging sorting and filtering options? PinmemberRamakrishna Pillai26-Nov-09 2:25 
GeneralGreat Article ! Pinmemberquangnd.edu23-Nov-09 5:29 
GeneralRe: Great Article ! PinmemberRamakrishna Pillai26-Nov-09 2:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140827.1 | Last Updated 20 Nov 2009
Article Copyright 2009 by Ramakrishna Pillai
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid