Real-World DataGrid Editing

Try this practical approach to editing DataGrid content.

DataStream

LANGUAGES: VB

TECHNOLOGIES: ASP.NET | ADO.NET | SQL Server

 

Real-World DataGrid Editing

Try this practical approach to editing DataGrid content.

 

By Wayne S. Freeze

 

Although DataGrids are useful for displaying tabular data, they leave a lot to be desired if you want to edit the data in the grid. Because you need to display all the fields in the grid, you easily could end up with a very wide Web page, which forces the user to scroll the page horizontally to view the data. To make this situation even worse, you need to add a couple of columns to the DataGrid that contain buttons allowing the user to edit and delete a particular row.

 

Rather than use this approach, you might consider using a separate page to edit a particular row of data. By using a separate page for editing, you can limit the number of columns you include in the DataGrid to only the most important columns. This keeps the overall width of the grid small enough to avoid horizontal scrolling. It also means you create a friendlier environment for editing a particular row of data.

 

This article expands the sample DataGrid program (available for download) developed over the last few DataStream articles to demonstrate this approach for editing data.

 

Link From the DataGrid

Because you are dealing with two independent pages, you need a method to communicate which row of data you want to edit from the DataGrid page to the edit page. The easiest way to do this is simply to add a parameter to the URL when the page is displayed and retrieve this parameter using the Request object. It's important that this parameter reference the primary key or some other value that identifies uniquely the row you want to edit. For example, this URL would load the page with the information for CustomerId 2:

 

Data11B.aspx?CustomerId=2

 

Next, convert one of the columns in the DataGrid into a hyperlink column. Stylistically, this column should contain a unique value - such as a name - though it isn't critical. You could use the primary key column, but you might want to drop it from the DataGrid, especially if it contains an Identity value. After all, this type of value rarely contains useful information to end users.

 

Within the DataGrid definition, you need to use an definition similar to the one shown below. This definition contains a few key attributes. The DataNavigateUrl FormatString attribute has a format string containing the URL to be generated. The DataNavigateUrlField contains the column from the bound table that will be inserted into the format string. The DataTextField contains the value that should be displayed in the in the DataGrid:

 

DataNavigateUrlFormatString="Data11B.aspx?CustomerId={0}"

DataTextField="Name" SortExpression="Name"

HeaderText="Customer Name">

 

Although the hyperlinks allow you to display an existing row, you need to add a hyperlink that will allow a visitor to add a new row to the database. One way to do this is to use a hyperlink like this:

 

Data11B.aspx?CustomerId=New

 

By substituting the value New in place of the primary key, you easily can detect it in the edit page and handle it appropriately. All of these changes result in the page you see in Figure 1.

 


Figure 1. The Customer List Web page displays a DataGrid with a hyperlink column, allowing visitors to jump to a new Web page where they can edit that particular row.

 

Retrieve the Edit Data

The edit page is straightforward, containing a table of column names and values, along with three hyperlink buttons that allow you to save or delete the row or return to the DataGrid page (see Figure 2).

 


Figure 2. The Edit Customer page contains complete information for the customer, including information that might not have been displayed on the DataGrid in an easily editable format.

 

In the Page_Load event (see Figure 3), you need to handle two basic conditions. The first condition is when the query string parameter contains a value of New. In this case, you merely need to display a blank page and let the visitor know they should enter the information for a new customer. The second is when the query string parameter contains a properly formatted primary key value. In this case the appropriate stored procedure is called to return the information about that particular customer and the information is copied to the Web form.

 

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)

 

Dim ds As DataSet

Dim dr As DataRow

Dim ConnectionStr As String = ConfigurationSettings.AppSettings("ConnStr")

Dim adpt As SqlDataAdapter

Dim conn As SqlConnection

Dim cmd As SqlCommand

Dim Id As Integer

 

If Not IsPostBack Then

   If Request.QuerySTring("CustomerId") Is Nothing Then

      Status.Text = "New customer"

      CustomerId.Text = "New"

 

   ElseIf Request.QueryString("CustomerId") = "New" Then

      Status.Text = "New customer"

      CustomerId.Text = "New"

 

   Else

      Try

         Status.Text = "Customer retrieved"

         Id = CInt(Request.QueryString("CustomerId"))

         ds = New DataSet()

         conn = New SqlConnection(ConnectionStr)

         cmd = New SqlCommand("GetCustomer", conn)

         cmd.CommandType = CommandType.StoredProcedure

         cmd.Parameters.Add("@CustomerId", SqlDbType.Int).Value = Id

         adpt = New SqlDataAdapter(cmd)

         adpt.Fill(ds, "Customer")

 

         if ds.Tables("Customer").Rows.Count = 0 Then

            Status.Text = "Customer not found."

 

         Else

            dr = ds.Tables("Customer").Rows(0)

            CustomerId.Text = dr("CustomerId")

            Name.Text = dr("Name")

            Street.Text = dr("Street")

            City.Text = dr("City")

            State.Text = dr("State")

            ZipCode.Text = dr("ZipCode")

            Phone.Text = dr("Phone")

            EMailAddress.Text = dr("EMailAddress")

            MailingList.Checked = dr("MailingList")

            Comments.Text = dr("Comments")

 

         End If

 

      Catch ex as InvalidCastException

         Status.Text = "Invalid Customer Id value."

 

      Catch ex As SqlException

         Status.Text = "Database error: " & ex.message

         If cmd.Connection.State <> ConnectionState.Closed Then

            cmd.Connection.Close()

 

         End If

 

      Catch ex As Exception

         Status.Text = "General error: " & ex.message

         If cmd.Connection.State <> ConnectionState.Closed Then

            cmd.Connection.Close()

 

         End If

 

      End Try

  

   End If

 

End If

Figure 3. The Page_Load event displays an empty form to enter a new customer. It also can retrieve information about a customer that exists in the database already.

 

The Page_Load event begins by checking the IsPostBack property so the information about a customer is loaded only when the page is first loaded. If the CustomerId parameter in the query string doesn't exist, the page request is treated as a new customer. Likewise, if CustomerId contains the value New, a blank form is returned.

 

If the CustomerId value contains something else, it will be converted to an integer and saved into the variable Id. If the conversion fails, the Catch clause will display an error message. Otherwise, a new instance of the DataSet class is created, along with a new SqlConnection object. Next, a SqlCommand object is created that will call the GetCustomer stored procedure. The value stored in Id is stored in the @CustomerId parameter associated with the stored procedure. Then a new SqlDataAdapter object is created using the SqlCommand object. Then the adapter's Fill method retrieves the requested data from the database into the DataSet object. Finally, if the DataSet object has a table containing at least one row, the values from the first row are copied to the Web form; otherwise an error message is displayed.

 

Update the Database

Once the data is displayed on the form, the user is free to change any value - except CustomerId, which is displayed using a Label control. When the user clicks on the Save Customer hyperlink button, the LinkButton1_Click event is fired (see Figure 4), saving the information from the form to the database.

 

Sub LinkButton1_Click(sender As Object, e As EventArgs)

 

Dim ConnectionStr As String = ConfigurationSettings.AppSettings("ConnStr")

Dim cmd As SqlCommand

Dim conn As SqlConnection

Dim id As Integer

 

Try

   Status.Text = "Customer saved"

 

   If CustomerId.Text = "New" Then

      id = -1

 

   Else

      id = CInt(CustomerId.Text)

 

   End If

 

   conn = New SqlConnection(ConnectionStr)

   cmd = New SqlCommand("PutCustomer", conn)

   cmd.CommandType = CommandType.StoredProcedure

   cmd.Parameters.Add("@CustomerId", SqlDbType.Int).Value = Id

   cmd.Parameters("@CustomerId").Direction = ParameterDirection.InputOutput

   cmd.Parameters.Add("@Name", SqlDbType.VarChar, 64).Value = Name.Text

   cmd.Parameters.Add("@Street", SqlDbType.VarChar, 64).Value = Street.Text

   cmd.Parameters.Add("@City", SqlDbType.VarChar, 64).Value = City.Text

   cmd.Parameters.Add("@State", SqlDbType.Char, 2).Value = State.Text

   cmd.Parameters.Add("@ZipCode", SqlDbType.VarChar, 10).Value = ZipCode.Text

   cmd.Parameters.Add("@Phone", SqlDbType.VarChar, 32).Value = Phone.Text

   cmd.Parameters.Add("@EMailAddress", SqlDbType.VarChar, 128).Value = EMailAddress.Text

   cmd.Parameters.Add("@MailingList", SqlDbType.Bit).Value = MailingList.Checked

   cmd.Parameters.Add("@Comments", SqlDbType.VarChar, 256).Value = Comments.Text

 

   cmd.Connection.Open()

   cmd.ExecuteNonQuery()

   cmd.Connection.Close()

 

   CustomerId.Text = cmd.Parameters("@CustomerId").Value.ToString

 

Catch ex as InvalidCastException

   Status.Text = "Invalid Customer Id value."

 

Catch ex As SqlException

   Status.Text = "Database error: " & ex.message

   If cmd.Connection.State <> ConnectionState.Closed Then

      cmd.Connection.Close()

 

   End If

 

Catch ex As Exception

   Status.Text = "General error: " & ex.message

   If cmd.Connection.State <> ConnectionState.Closed Then

      cmd.Connection.Close()

 

   End If

 

End Try

 

End Sub

Figure 4. The LinkButton1_Click event saves the information from the Web form to the database using a stored procedure.

 

This routine begins by assuming everything will work properly. If the CustomerId field contains New, Id is assigned a value of -1; otherwise it will contain the real CustomerId value. Next, a new stored procedure object is created, which calls the PutCustomer stored procedure. The PutCustomer stored procedure contains one parameter for each value displayed on the Web form. As each parameter is added to the SqlCommand's Parameters collection, the appropriate type information is supplied and the appropriate value from the Web form is saved. Next, the connection object is opened, then the stored procedure is executed and the connection object is closed.

 

Note that one of the parameters of the stored procedure is special. The CustomerId parameter works in both directions. This means the stored procedure can return a value as well as use the supplied value. In this situation, if CustomerId doesn't exist in the database, the stored procedure inserts a new row into the database and returns the new value for CustomerId through this parameter. This value is saved into the CustomerId Label control when the stored procedure has finished.

 

Figure 5 contains the PutCustomer stored procedure. This routine begins by looking for the row associated with the value stored in @CustomerId. If the row doesn't exist, an Insert statement is used to add the row to the Customers table, and the value stored in @@Identity is saved in the @CustomerId parameter. Otherwise, an Update statement is executed to save the new values into the database.

 

CREATE Procedure PutCustomer

 

@CustomerId Int Out,

@Name Varchar(64),

@Street Varchar(64),

@City Varchar(64),

@State Char(2),

@ZipCode  Varchar(10),

@Phone Varchar(32),

@EMailAddress Varchar(128),

@MailingList Bit,

@Comments Varchar(256)

 

As

 

If Exists(Select * From Customers Where [email protected])

   Update Customers

      Set

         [email protected],

         [email protected],

         [email protected],

         [email protected],

         ZipCode=ZipCode,

         [email protected],

         [email protected],

         [email protected],

         [email protected]

      Where [email protected]

Else

   Begin

      Insert Into Customers(

         Name,

         Street,

         City,

         State,

         ZipCode,

         Phone,

         EMailAddress,

         MailingList,

         Comments)

   Values(

      @Name,

      @Street,

      @City,

      @State,

      @ZipCode,

      @Phone,

      @EMailAddress,

      @MailingList,

      @Comments)

 

    Set @CustomerId = @@Identity

 

   End

Figure 5. The PutCustomer stored procedure takes a series of parameters and either inserts a new row into the Customers table (if the value of @CustomerId is less than zero) or updates the Customers table corresponding to @CustomerId.

 

Finish the Job

The Delete Customer LinkButton calls a stored procedure to delete the specified customer. It traps an attempt to delete a new customer and returns an error message to the user. Otherwise the Visual Basic code is similar to the code executed by the Save Customer LinkButton; the main difference is the DeleteCustomer stored procedure has only one parameter - @CustomerId.

 

The event associated with the Return to Customer List LinkButton contains a single call to Response.Redirect that returns the visitor back to the original DataGrid page. Response.Redirect was used rather than Server.Transfer because there is no need to hide the new page's URL from the visitorIit is important that the DataGrid page get a fresh copy of the data from the database each time it's displayed. Otherwise the data stored in the Session object would not reflect the latest changes.

 

Wayne S. Freeze is a full-time computer book author with more than a dozen titles to his credit, including Windows Game Programming with Visual Basic and DirectX (Que) and Unlocking OLAP with SQL Server and Excel 2000 (Hungry Minds). He has more than 25 years of experience using all types of computers, from small, embedded microprocessor control systems to large-scale IBM mainframes. Freeze has a master's degree in management information systems as well as degrees in computer science and engineering. You can visit his Web site at http://www.JustPC.com and send him e-mail at mailto:[email protected]. He loves reading e-mail from his readers, whose ideas, questions, and insights often provide inspiration for future books and articles.

 

 

 

 

Hide comments

Comments

  • Allowed HTML tags: <em> <strong> <blockquote> <br> <p>

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.
Publish