Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET

Asp Grid View with custom column for Text box and Button control for update and display

2.00/5 (3 votes)
11 Dec 2017CPOL3 min read 11.1K  
Introduction We use Asp grid view to display various information and we may have come across multiple scenarios where we

Introduction

We use Asp grid view to display various information and we may have come across multiple scenarios where we want to create a grid with text boxes and button in the grid view for each column. To achieve this asp data grid gives us this option with edit item template where we can create a text boxes and also add Edit, Update and Cancel button, but there are a few downside to using edit item template like creating custom button etc.

When trying to achieve this I faced an issue when trying to rebind the data to the grid again. I got the error “Invalid postback or callback argument.  Event validation is enabled using <pages enableEventValidation=”true”/> in configuration or <%@ Page EnableEventValidation=”true” %> in a page.  For security purposes, this feature verifies that arguments to postback or callback events originate from the server control that originally rendered them.  If the data is valid and expected, use the ClientScriptManager.RegisterForEventValidation method in order to register the postback or callback data for validation.“.

To Fix this I tried to set EnableEventValidation to false and also ValidateRequest to false, but doing this would not trigger the row command event from the button in the grid view. The second fix was to rebind the data in Page_PreRender and it fixed the issue

Using the code

The example I used to demonstrate this is is a grid with order details and the last column will have a text box to accept the approver id and button to approve and clear the data.

Asp Grid View Sample Image
Asp Grid View Sample Image

The sample project has an asp .net web application and data layer. The data layer is straight forward and there is two separate classes to Get the data (GetData) from database and another class to Update the data in database (UpdateData).

Visual Studio Sample Project Structure
Sample Project Structure (Visual Studio)

The code is simple, we create a normal asp grid view and create columns. The Last column which is going to contain the text box and the buttons is placed in a template field and inside the item template.

A HTML section element will contain both the textbox, label and buttons and outside the section element is a label to display the information from database if the order is already approved.

 

        //<asp:gridview autogeneratecolumns="false" id="aspGridView" onrowcommand="aspGridView_RowCommand" onrowdatabound="aspGridView_RowDataBound" runat="server" style="margin-top:20px;" width="100%">
//                <columns>
//                    <asp:boundfield datafield="ORD_NUM" headerstyle-horizontalalign="Center" headertext="Order Number" itemstyle-horizontalalign="Center">
//                    <asp:boundfield datafield="ORD_AMOUNT" headerstyle-horizontalalign="Center" headertext="Order Amount" itemstyle-horizontalalign="Center">
//                    <asp:boundfield datafield="ORD_DATE" headerstyle-horizontalalign="Center" headertext="Order Date" itemstyle-horizontalalign="Center">
//                    <asp:boundfield datafield="CUST_NAME" headerstyle-horizontalalign="Center" headertext="Customer Date" itemstyle-horizontalalign="Center">
//                    <asp:boundfield datafield="ORD_DESCRIPTION" headerstyle-horizontalalign="Center" headertext="Order Description" itemstyle-horizontalalign="Center">
//                    <asp:templatefield headertext="Approve Order">
//                        <itemtemplate>
//<section id="ApprovalSection" runat="server" style="margin-top: 5px;">
//<div class="approveUserIdSection">
//                                    <asp:textbox clientidmode="Predictable" id="txtApproveId" maxlength="11" placeholder="Approver ID" runat="server"></asp:textbox>
//                                    <asp:label clientidmode="Predictable" cssclass="validatorMsgGrid" id="alertMsg" runat="server"></asp:label>                                  
//</div>
//<div>
//                                    <asp:button clientidmode="Predictable" commandargument="<%#((GridViewRow)Container).RowIndex %>" commandname="ApproveOrder" cssclass="button" id="btnApproveOrder" runat="server" text="Approve Order">
//                                    <asp:button clientidmode="Predictable" cssclass="button" id="btnClear" runat="server" text="Clear">
//                                </asp:button></asp:button></div>
//</section>
//                            <asp:label cssclass="approvedByMsg" id="txtapprovedBy" runat="server" text="<%# "Approved By " + Eval("APPROVAL_ID") %>" visible="false"></asp:label>
//                        </itemtemplate>
//                    </asp:templatefield>
//                </asp:boundfield></asp:boundfield></asp:boundfield></asp:boundfield></asp:boundfield></columns>
//            </asp:gridview>

 

The approve order button click is handled in the grid views RowCommand and the command is identified by the CommandName. The button has the CommandArgument which is the row index and we use this row index to identify the row that triggered the event and identify the controls to use in handler.

 

    //<div>
//  <asp:Button ID="btnApproveOrder" ClientIDMode="Predictable" Text="Approve Order" runat="server" CssClass="button" CommandName="ApproveOrder" CommandArgument="<%#((GridViewRow)Container).RowIndex %>" />
//  <asp:Button ID="btnClear" ClientIDMode="Predictable" Text="Clear" runat="server" CssClass="button" />
//</div>

 

        //protected void aspGridView_RowCommand(object sender, GridViewCommandEventArgs e)
//       {
//           int rowIndex = 0;
//           string ordernum = string.Empty;
//           string approverid = string.Empty;
//           UpdateData updateDataInDb = null;
//           try
//           {
//               switch (e.CommandName)
//               {
//                   case "ApproveOrder":
//                       rowIndex = Convert.ToInt32(e.CommandArgument);
//                       GridViewRow row = aspGridView.Rows[rowIndex];
//                       approverid = ((TextBox)row.FindControl("txtApproveId")).Text.ToString().Trim();
//                       ordernum = row.Cells[0].Text.ToString().Trim();
//                       updateDataInDb = new UpdateData();
//                       updateDataInDb.UpdateApproverId(ordernum, approverid);
/                       break;
//               }
//
//            }
//            catch (Exception ex)
//            {
//                throw ex;
//            }
//        }

 

If data is already available, I.e the order is already approved then the textbox and buttons are hidden and the information is displayed in the column, other rows that does not have data will display the approval section. This is handled in the RowDataBound event of the gridview.

On each row, codes checks if the binding data has the information, if the information is available then we find the control and hide or display them (this can be seen from the screenshot of the gridview above).

 

        //protected void aspGridView_RowDataBound(object sender, GridViewRowEventArgs e)
//        {
//            Button approveOrderBtn = null;
//            Button clearnBtn = null;
//            DataRowView datarow = null;
//            Label approvedBy = null;
//            Label alertText = null;
//            TextBox approvalid = null;
//            HtmlGenericControl approvalSection = null;
//            try
//            {
//                if (e.Row.RowType == DataControlRowType.DataRow)
//                {
//                    datarow = (DataRowView)e.Row.DataItem;
//                    if (!string.IsNullOrEmpty(datarow[5].ToString()))
//                    {
//                        approvalSection = (HtmlGenericControl)e.Row.FindControl("ApprovalSection");
//                        approvalSection.Visible = false;
//                        approvedBy = (Label)e.Row.FindControl("txtapprovedBy");
//                        approvedBy.Visible = true;
//                    }
//                    else
//                    {
//                        approveOrderBtn = (Button)e.Row.FindControl("btnApproveOrder");
//                        clearnBtn = (Button)e.Row.FindControl("btnClear");
//                        alertText = (Label)e.Row.FindControl("alertMsg");
//                        approvalid = (TextBox)e.Row.FindControl("txtApproveId");
//                        if (approveOrderBtn != null)
//                            approveOrderBtn.OnClientClick = "return ValidateInput('" + approvalid.ClientID + "','" + alertText.ClientID + "')";
//                        if (clearnBtn!=null)
//                            clearnBtn.OnClientClick= "return ClearInputField('"+approvalid.ClientID+"')";
//                    }
//                }
//            }
//            catch (Exception ex)
//            {
//                throw ex;
//            }
//        }

 

There are some basic validation on the button click and as you can see from the code above that is achieved by javascript and you can see that this validation functions are attached to the button during the RowDataBound event.

Source Code

https://github.com/rbipin/AspGridView_WithCustomColumn.git

 

License

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