In this tutorial, we will be looking at how we can replicate the built-in feature of the GridView control and use a Repeater to edit data inline and almost without delay. We will be using AJAX to call asynchronous postbacks, and allow editing of data a row at a time.
This tutorial was written with ASP.NET 3.5 using Visual Studio 2008. If you are using 2005 with ASP.NET 2.0, then you will need to download the AJAX Extensions from Microsoft.
The first thing we will do is to add the ScriptManager to our ASPX page, which will manage all of our AJAX calls:
| <asp:ScriptManager ID="SM1" runat="server" /> |
Next, we can add an UpdatePanel to the page:
<asp:UpdatePanel ID="UP1" runat="server" RenderMode="Inline" UpdateMode="Conditional">
<ContentTemplate>
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
</HeaderTemplate>
<ItemTemplate>
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel> |
We migrated our web sites to Server Intellect over one weekend and the setup was so smooth that we were up and running right away. They assisted us with everything we needed to do for all of our applications. With Server Intellect's help, we were able to avoid any headaches!
We will make use of the Header template to start a HTML table, and the Footer template to end it. The Content template will be used for the data we will be displaying. For this example, we will display data from an XML file. The XML will look something like this:
<?xml version="1.0" encoding="utf-8" ?>
<People>
<Person>
<ID>1</ID>
<Name>Freddie Cosgrove</Name>
<Age>41</Age>
<Country>USA</Country>
</Person>
<Person>
<ID>2</ID>
<Name>Regina Filange</Name>
<Age>33</Age>
<Country>Sweden</Country>
</Person>
<Person>
<ID>3</ID>
<Name>Rod Hull</Name>
<Age>67</Age>
<Country>UK</Country>
</Person>
</People> |
Here, we define three data records each with an ID, name, Age, and Country. We will use this XML file to display in the repeater. We can do this on page load like so:
protected void Page_Load(object sender, EventArgs e)
{
DataSet xmlData = new DataSet();
xmlData.ReadXml(MapPath("data.xml"));
Repeater1.DataSource = xmlData;
Repeater1.DataBind();
} |
We chose Server Intellect for its dedicated servers, for our web hosting. They have managed to handle virtually everything for us, from start to finish. And their customer service is stellar.
This code simply reads the XML from the external file and then assigns it to our Repeater to display. First though, we need to build out our repeater template. Let's go ahead and create a HTML table to display:
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<table><tr><th>Name</th><th>Age</th><th>Country</th><th>Edit</th></tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
</td>
<td>
</td>
<td>
</td>
<td>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater> |
In each of the table cells, we will place a Literal control and a TextBox control - making the TextBox control hidden by default. We will also assign the values of the datasource to each control:
<ItemTemplate>
<tr>
<td>
<asp:Literal ID="lit_Name" runat="server" Text='<%# Eval("Name") %>' />
<asp:TextBox ID="fld_Name" runat="server" Text='<%# Eval("Name") %>' Visible="false" />
</td>
<td>
<asp:Literal ID="lit_Age" runat="server" Text='<%# Eval("Age") %>' />
<asp:TextBox ID="fld_Age" runat="server" Text='<%# Eval("Age") %>' Columns="4" Visible="false" />
</td>
<td>
<asp:Literal ID="lit_Country" runat="server" Text='<%# Eval("Country") %>' />
<asp:TextBox ID="fld_Country" runat="server" Text='<%# Eval("Country") %>' Visible="false" />
</td>
<td>
<asp:LinkButton ID="lnk_Edit" runat="server" Text="Edit" CommandName="EditThis" />
<asp:LinkButton ID="lnk_Cancel" runat="server" Text="Cancel" CommandName="CancelEdit" Visible="false" />
</td>
</tr>
</ItemTemplate> |
Notice we have included LinkButtons with CommandNames. We will use these on the onItemCommand event of the Repeater. To create a handler for this event, either select the Repeater in Design view and double-click the onItemCommand event in the Properties window, or add the following code (You'll also need to include the method name in the OnItemCommand attribute on the Repeater control):
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
} |
Here, we are going to check the CommandName, as we have two. Then we will set the visibility of the Literal and TextBox controls:
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
RepeaterItem item = e.Item;
Literal lit_Name = (Literal)item.FindControl("lit_Name");
TextBox fld_Name = (TextBox)item.FindControl("fld_Name");
Literal lit_Age = (Literal)item.FindControl("lit_Age");
TextBox fld_Age = (TextBox)item.FindControl("fld_Age");
Literal lit_Country = (Literal)item.FindControl("lit_Country");
TextBox fld_Country = (TextBox)item.FindControl("fld_Country");
LinkButton lnk_Edit = (LinkButton)item.FindControl("lnk_Edit");
LinkButton lnk_Cancel = (LinkButton)item.FindControl("lnk_Cancel");
if (e.CommandName == "EditThis")
{
lit_Name.Visible = false;
fld_Name.Visible = true;
lit_Age.Visible = false;
fld_Age.Visible = true;
lit_Country.Visible = false;
fld_Country.Visible = true;
lnk_Edit.Text = "Save";
lnk_Cancel.Visible = true;
}
else if (e.CommandName == "CancelEdit")
{
lit_Name.Visible = true;
fld_Name.Visible = false;
lit_Age.Visible = true;
fld_Age.Visible = false;
lit_Country.Visible = true;
fld_Country.Visible = false;
lnk_Edit.Text = "Edit";
lnk_Cancel.Visible = false;
}
} |
We moved our web sites to Server Intellect and have found them to be incredibly professional. Their setup is very easy and we were up and running in no time.
Now if we run this web application, we will be able to click the Edit link for each item in the XML file and we will be provided with a textbox to edit the data. You can add a third update command to save the data back to the XML file.
The ASPX page will look something like this:
<form id="form1" runat="server">
<asp:ScriptManager ID="SM1" runat="server" />
<asp:UpdatePanel ID="UP1" runat="server" RenderMode="Inline" UpdateMode="Conditional">
<ContentTemplate>
<asp:Repeater ID="Repeater1" runat="server" OnItemCommand="Repeater1_ItemCommand">
<HeaderTemplate>
<table><tr><th>Name</th><th>Age</th><th>Country</th><th>Edit</th></tr>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<asp:Literal ID="lit_Name" runat="server" Text='<%# Eval("Name") %>' />
<asp:TextBox ID="fld_Name" runat="server" Text='<%# Eval("Name") %>' Visible="false" />
</td>
<td>
<asp:Literal ID="lit_Age" runat="server" Text='<%# Eval("Age") %>' />
<asp:TextBox ID="fld_Age" runat="server" Text='<%# Eval("Age") %>' Columns="4" Visible="false" />
</td>
<td>
<asp:Literal ID="lit_Country" runat="server" Text='<%# Eval("Country") %>' />
<asp:TextBox ID="fld_Country" runat="server" Text='<%# Eval("Country") %>' Visible="false" />
</td>
<td>
<asp:LinkButton ID="lnk_Edit" runat="server" Text="Edit" CommandName="EditThis" />
<asp:LinkButton ID="lnk_Cancel" runat="server" Text="Cancel" CommandName="CancelEdit" Visible="false" />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
</form> |
And then the entire code-behind will look something like this:
using System;
using System.Collections;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
DataSet xmlData = new DataSet();
xmlData.ReadXml(MapPath("data.xml"));
Repeater1.DataSource = xmlData;
Repeater1.DataBind();
}
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
RepeaterItem item = e.Item;
Literal lit_Name = (Literal)item.FindControl("lit_Name");
TextBox fld_Name = (TextBox)item.FindControl("fld_Name");
Literal lit_Age = (Literal)item.FindControl("lit_Age");
TextBox fld_Age = (TextBox)item.FindControl("fld_Age");
Literal lit_Country = (Literal)item.FindControl("lit_Country");
TextBox fld_Country = (TextBox)item.FindControl("fld_Country");
LinkButton lnk_Edit = (LinkButton)item.FindControl("lnk_Edit");
LinkButton lnk_Cancel = (LinkButton)item.FindControl("lnk_Cancel");
if (e.CommandName == "EditThis")
{
lit_Name.Visible = false;
fld_Name.Visible = true;
lit_Age.Visible = false;
fld_Age.Visible = true;
lit_Country.Visible = false;
fld_Country.Visible = true;
lnk_Edit.Text = "Save";
lnk_Cancel.Visible = true;
}
else if (e.CommandName == "CancelEdit")
{
lit_Name.Visible = true;
fld_Name.Visible = false;
lit_Age.Visible = true;
fld_Age.Visible = false;
lit_Country.Visible = true;
fld_Country.Visible = false;
lnk_Edit.Text = "Edit";
lnk_Cancel.Visible = false;
}
}
} |