Devils Work

—Blog By DotNetRuler

Archive for March, 2009

GridView Row Edit, Delete and Update

Posted by DotnetRuler on March 27, 2009

In this Post I am going to explain a simple light weight GridView Edit, Delete, and Update functionality.  We are going to apply this functionality on Northwind Database, Employee table.

Following are the screen shots.

normal-vieweditmodeview

 

First of all I am going to explain about creating a Connection String.

Connection String has mainly 3 properties.

DataSource — DataSource is your SQL Server name.

Initial Catalog — Your Database name (Northwind in this case).

Integrated Security – True

Integrated Security will access the SQL Server with the current windows identity established on the Operating System. For more information about Integrated Security refer this. We usually place the connection string in the Web.config file under “Configuration ==> ConnectionStrings” section.

Here is my connection string.

<connectionStrings>

 

    <add name=NorthwindConnectionString connectionString=Data Source=*****(SQL Server Name);Initial Catalog=NorthWind;Integrated Security=True;/>

  </connectionStrings>

To learn more about different type of connection strings refer this.

Then, after we are done with your connection string in the Web.config file let’s move on to the C# code.

The Following Snippet is to bind GridView.

private void BindGridData()

  {

    using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings[“NorthwindConnectionString”].ConnectionString))

      {

          conn.Open();

          using (SqlCommand comm = new SqlCommand(“select E.EmployeeID,E.FirstName,E.LastName,E.Title,E.Country from Employees E”, conn))

          {

               SqlDataAdapter da = new SqlDataAdapter(comm);

               DataSet ds = new DataSet();

               da.Fill(ds);

               GridView1.DataSource = ds;

               GridView1.DataBind();

          }

      }

  }

The First Line using statement allows the programmer to specify when objects that use resources should release them. The object provided to the using statement must implement the IDisposable interface. This interface provides the Dispose method, which should release the object’s resources. Refer this for Complete Reference.

The following is how we write asp.net GridView web server control code in aspx page.  I guess most of the people will be aware of the GridView events. For complete Reference refer this.

In the Code you can see I put AutoGenerateColumns=”false”. That means I have to write column names whatever I want to show to the user. If we put AutoGenerateColumns=”True”, that means u don’t have to write any custom code on your page and user can see each and every column in your dataset or datatable whatever you are binding to your gridview.

It is always good to have some control on these instead of giving up everything to it. I want to hide EmployeeID   for the user.  But I need it for querying the databse while updating and deleting  the user stuff.  So

How can we hide a column in a GridView and access it in the Code behind ?

We can do this in several ways!!! , But depends on what column we want to hide. I always follow this method.

Writing a Template Field and making it invisible.  In the template field I will Place a label or some controls, So that it’s very easy to access those controls in the code behind by using FindControl method.

Suppose if we are trying to hide primary key of our table, there is actually no need to hide. GridView has a Property called DataKeyNames. We have to give our primary key column name to it. It will do the rest.  we can see how we can access that in the code behind in the GridView_Rowupdating Event which I am going to explain later part of this article.

What is TemplateField, ItemTemplate, and EditItemTemplate?

We will use Template Field, whenever we want to define some custom control in the data bound controls like GridView, DataGrid or DataRepeater.

ItemTemplate is the content to display for the items in the TemplateField. 

EditItemTemplate as the name itself it is the content to display for the items in the TemplateField when it is in Edit mode. Refer this for complete reference.

Take this simple Snippet.

<asp:TemplateField HeaderText=”LastName”>

     <ItemTemplate>

            <asp:Label runat=”server” ID=”LastName” Text=’<%#Eval(“LastName”) %> />

     </ItemTemplate>

     <EditItemTemplate>

          <asp:TextBox runat=”server” ID=”txtLastName” Text=’<%#Eval(“LastName”) %> />

          <asp:RequiredFieldValidator runat=”server” ID=”rfdLastName”                                       ControlToValidate=”txtLastName” ValidationGroup=”var1″ ErrorMessage=”*” />

     </EditItemTemplate>

</asp:TemplateField>

 

In the above Snippet you are seeing a label in Item Template that means whenever we are showing GridView to the user Label will be visible to the user. If he clicks edit (or) in the edit mode he can be able to see the Textbox.

<asp:BoundField HeaderText=”FirstName” DataField=”FirstName” ReadOnly=”false”/>

The above piece of code will also do the same as label in ItemTemplate and Textbox in the EditItemTemplate. By default all the boundfields will be trasferred as Textboxes in Edit Mode. To avoid this we need to keep the property ReadOnly as false, Then in the edit mode nothing will happenes. It just visible like a label.

 

The reason I use TemplateField instead of BoundField is that, it is very easy to grab those controls in the codebehind if we user labels or textboxes. In case of the bound field’s we need to check what column it is and need to use index of that cloumn, which is little hard and even in future if we change the column order  we have to change the code too.

 

<asp:GridView ID=”GridView1″ runat=”server” GridLines=”None” AutoGenerateColumns=”false”

      AlternatingRowStyle-BackColor=”#EEEEEE” EditRowStyle-BorderColor=”Red”

      onrowcancelingedit=”GridView1_RowCancelling” onrowcommand=”GridView1_RowCommand”

      onrowdeleting=”GridView1_RowDeleting” onrowediting=”GridView1_RowEditing”

      onrowupdating=”GridView1_RowUpdating” DataKeyNames=”EmployeeID”>           

      <Columns>           

         <asp:TemplateField Visible=”false” HeaderText=”EmployeeID”>

            <ItemTemplate>

              <asp:Label runat=”server” ID=”EmployeeID” Text=’<%#Eval(“EmployeeID”)%> />

            </ItemTemplate>

         </asp:TemplateField>

         <%–<asp:BoundField HeaderText=”FirstName” DataField=”FirstName” />–%>

 

         <asp:TemplateField HeaderText=”LastName”>

 

            <ItemTemplate>

              <asp:Label runat=”server” ID=”LastName” Text=’<%#Eval(“LastName”) %> />

            </ItemTemplate>

 

            <EditItemTemplate>

            <asp:TextBox runat=”server” ID=”txtLastName” Text=’<%#Eval(“LastName”) %> />

            <asp:RequiredFieldValidator runat=”server” ID=”rfdLastName”                    ControlToValidate=”txtLastName” ValidationGroup=”var1″ ErrorMessage=”*” />

            </EditItemTemplate>

 

         </asp:TemplateField>

         <asp:TemplateField HeaderText=”Title”>

 

            <ItemTemplate>

              <asp:Label runat=”server” ID=”Title” Text=’<%#Eval(“Title”) %> />

            </ItemTemplate>

 

            <EditItemTemplate>

              <asp:TextBox runat=”server” ID=”txtTitle” Text=’<%#Eval(“Title”) %> />

              <asp:RequiredFieldValidator runat=”server” ID=”rfdTitle”                       ControlToValidate=”txtTitle” ValidationGroup=”var1″ ErrorMessage=”*” />

            </EditItemTemplate>

 

         </asp:TemplateField>

 

         <asp:TemplateField HeaderText=”Country”>

        

           <ItemTemplate>

             <asp:Label runat=”server” ID=”Country” Text=’<%#Eval(“Country”) %> />

           </ItemTemplate>

 

           <EditItemTemplate>

             <asp:TextBox runat=”server” ID=”txtCountry” Text=’<%#Eval(“Country”) %> />

             <asp:RequiredFieldValidator runat=”server” ID=”rfdCountry”                 ControlToValidate=”txtCountry” ValidationGroup=”var1″ ErrorMessage=”*” />

           </EditItemTemplate>

 

          </asp:TemplateField>

 

      <asp:TemplateField HeaderText=”Action”>

 

      <ItemTemplate>

      <asp:LinkButton ID=”btnEdit” Text=”Edit” runat=”server” CommandName=”Edit” />

      <br />

      <asp:LinkButton ID=”btnDelete” Text=”Delete” runat=”server” CommandName=”Delete” />

      </ItemTemplate>

 

      <EditItemTemplate>

      <asp:LinkButton ID=”btnUpdate” Text=”Update” runat=”server” CommandName=”Update” />

      <asp:LinkButton ID=”btnCancel” Text=”Cancel” runat=”server” CommandName=”Cancel” />

      </EditItemTemplate>

 

      </asp:TemplateField>

 

   </Columns>

</asp:GridView>

If you see the Last TemplateField part in the above code, I am using the link buttons for edit, update, delete and cancel. May be you may think why am I using link buttons as we are provided with some command field buttons by GridView.

1)      If we use command buttons we have less control on them while doing validations, i.e. while assigning validation groups.

2)      Secondly if you want to include a custom field (some button or link) in the same column it’s not possible.

If we use proper command names for the buttons like “EDIT”, “DELETE”, “UPDATE”, “CANCEL” these will also trigger the appropriate GridView Events.

Ok let’s move on to Code behind what we have to do when user clicks Edit, Delete, Update and Cancel

When we click on Edit the OnRowEditing event will be fired. You can see the C# code below

protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)

{

   GridView1.EditIndex = e.NewEditIndex;

   BindGridData();

}

In the above code snippet as you see GridViewEditEventArgs will give the row number whatever you are editing by NewEditIndex property. So GridView will put the appropriate row into the Edit Mode by assigning row number to its EditIndex property. Then again we have to call that BindGridData () method to bind data for the textboxes.

So once after done with editing data, if we click update the following method will be triggered. It will call OnRowUpdating Event.  

1)      The First line is to get the Primary Key of the table using DataKeyNames Property of GridView.

2)      The Second line is to access the value of the invisible column.

protected void GridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)

{

   string s = GridView1.DataKeys[e.RowIndex].Value.ToString();           

   Label EmployeeID = GridView1.Rows[e.RowIndex].FindControl(“EmployeeID”) as Label;

   TextBox LastName = GridView1.Rows[e.RowIndex].FindControl(“txtLastName”) as TextBox;

   TextBox Title = GridView1.Rows[e.RowIndex].FindControl(“txtTitle”) as TextBox;

   TextBox Country = GridView1.Rows[e.RowIndex].FindControl(“txtCountry”) as TextBox;

   String UpdateQuery = string.Format(“UPDATE Employees SET LastName='{0}’,

                        Title='{1}’,Country='{2}’ WHERE EmployeeID = {3}”,LastName.Text, Title.Text, Country.Text, Convert.ToInt32(EmployeeID.Text));

 

    GridView1.EditIndex = -1;

    BindGridData(UpdateQuery);

}

Once we access the required fields in the code behind, we need to update the data in the database and show the updated data to the user. So am calling the method BindGridData method which is overloaded . I am passing Update Query as a parameter to it. You can see that method in the following snippet.

private void BindGridData(string Query)

{

  string connectionstring  =        ConfigurationManager.ConnectionStrings[“NorthwindConnectionString”].ConnectionString;

 

  using (SqlConnection conn = new SqlConnection(connectionstring))

  {

    conn.Open();

    using (SqlCommand comm = new SqlCommand(Query +

                  “;select E.EmployeeID,E.FirstName,E.LastName,E.Title,E.Country from Employees E”, conn))

    {

        SqlDataAdapter da = new SqlDataAdapter(comm);

        DataSet ds = new DataSet();

        da.Fill(ds);

        GridView1.DataSource = ds;

        GridView1.DataBind();

    }

  }

}

If the user click cancels the following event (OnRowCancelling) will be fired. When you are setting the value of the EditIndex to -1 that means you are exiting from the editmode.  So i.e. when user clicks cancel, here we are exiting from the editmode and rebinding the data to the GridView by calling BindGridData method.

protected void GridView1_RowCancelling(object sender, GridViewCancelEditEventArgs e)

{

    GridView1.EditIndex = -1;

    BindGridData();

}

If the user clicks the Delete button OnRowDeleting event will be fired. The following is the code for that event. Going into that code we are trying to get the primary key of the employee table(EmployeeID) by using GridView DataKeyNames and then  pass the Query to the BindGridData method to bind the updated data to the GridView.

protected void GridView1_RowDeleting(object sender, GridViewDeleteEventArgs e)

{

    string EmployeeID = GridView1.DataKeys[e.RowIndex].Value.ToString();

    string Query = “delete Employee where Employee.EmployeeID = “ + EmployeeID;

    BindGridData(Query);

}

 

Happy Coding .

Keep Rocking as always J

DotNetRuler. 

Advertisements

Posted in ASP.NET, Grid View | Tagged: , | 67 Comments »

multiple file upload control Using JavaScript

Posted by DotnetRuler on March 18, 2009

In this Post I am going to explain about Multiple File Upload Control Designed at the Client side. This Control is an Extension for the Example provided in the ASP.NET videos section.

You can see the Video here.

The Main Purpose of Creating This control is

1)      We cannot Save the State of an ASP.NET File Upload Control between Post backs.  We can create a Asp.NET textboxes or other Controls Dynamically (by Recreating and Reassigning the values to the Controls). But Due to security Issue You cannot reassign a File path to an ASP.NET File upload Control. [“File System is a part of Operating System”]

I have added these features to the existing control developed in the video.

1)      You  can have a textbox and a dropdown button

Textbox is for the description and Dropdown is for giving an option for the user to categorizing the uploaded File.

2)      I have added an option to remove if users don’t want the added control on the Page.

The Following is the Snap Shot of the Control.

Single File

singlefile

Multiple Files

multipleFiles

I will be explaining the code by taking it into small pieces.

I am placing this whole control in an user control and created an event handler to handle the Upload button event in the main page (aspx).

The Code that you are seeing below is the Code in the ascx page.

<body onload=”FileType()”>

    <table>

        <tr>

            <td >

                <asp:Image runat=”server” ID=”Add” Style=”cursor: pointer; ImageUrl=”~/add.png” onClick=”addFileUploadBox()” />

                <a id=”Addcontrol” style=”cursor: pointer; onclick=”addFileUploadBox()”><b>Add</b></a>

                <asp:ImageButton runat=”server” ID=”Image1″ Style=”cursor: pointer; ImageUrl=”~/Upload.png” OnClick=”btnUpload_Click” />

                <asp:LinkButton ID=”btnUpload” Style=”background: none; cursor: pointer; text-decoration: none; color: Black; Font-Bold=”true” runat=”server” Text=”Upload” OnClick=”btnUpload_Click” />

            </td>

        </tr>

        <tr>

            <td >

                <asp:Label ID=”Label1″ runat=”server” Text=”File Upload Control” Font-Bold=”true” Font-Underline=”true” Style=”margin-left: 60px; />

                <asp:Label ID=”Label2″ runat=”server” Text=”Description” Font-Bold=”true” Font-Underline=”true” Style=”margin-left: 235px; />

                <asp:Label ID=”Label3″ runat=”server” Text=”Type” Font-Bold=”true” Font-Underline=”true” Style=”margin-left: 85px; />

            </td>

        </tr>

        <tr>

            <td >

                <p id=”upload-area”>

                    <input id=”File1″ type=”file” runat=”server” size=”45″ />

                    <input id=”Text1″ type=”text” name=”Text1″ style=”margin-left: 5px; size=”25″ />

                </p>

            </td>

        </tr>

    </table>

</body>

This is Simple Piece of code which initially control is having.  On body load I am calling a javascript function FileType().

In this Function I am adding a html select Control on the fly. This was done using JSON (Java Script Object Notation). In this Example I am just using a simple list. You can even bind this Select Control to the DataSource.

The function is as follows…

    function FileType(){

        var uploadArea = document.getElementById(“upload-area”);

        var newTypeDdl = document.createElement(“select”);

        var types = <asp:Literal ID=“typesJson” runat=“server” />;

        for(var t in types) {

            var typ = types[t];

            newTypeDdl.options.add(new Option(typ, typ));

        }

        newTypeDdl.setAttribute(“id”, “Select1”);

        newTypeDdl.setAttribute(“name”, “Select1”);

        newTypeDdl.style.marginLeft = “8px”;

        uploadArea.appendChild(newTypeDdl);

    }

I am Creating a ASP Server Side Literal Control Which I will access in the code behind and bind the list to the HTML Select Control. You can see the Code behind code below.

protected void Page_Load(object sender, EventArgs e)

        {

            List<string> fakeTypes = new List<string>();

            fakeTypes.Add(“Project1”);

            fakeTypes.Add(“Project2”);

            fakeTypes.Add(“Project3”);

            fakeTypes.Add(“Project4”);

            StringBuilder sb = new StringBuilder();

            foreach (string t in fakeTypes)

            {

                if (sb.Length > 0)

                {

                    sb.Append(“,”);

                }

                sb.AppendFormat(“”{0}””, t);

            }

            typesJson.Text = string.Format(“[{0}]”, sb);

            typesJson1.Text = string.Format(“[{0}]”, sb);//For Dynamically                                                                                                                                           added Select Control

        }

The following Code Snippet will be called when User wants to add one more file. This will create a html input of type File and a html textbox and html select Control.

function addFileUploadBox() {

 

        // The new box needs a name and an ID

        if (!addFileUploadBox.lastAssignedId)

            addFileUploadBox.lastAssignedId = 2;

 

        if (!document.getElementById || !document.createElement)

            return false;

 

        var uploadArea = document.getElementById(“upload-area”);

 

        if (!uploadArea)

            return;

 

        var container = document.createElement(“div”);

       container.setAttribute(“id”, “Div” + addFileUploadBox.lastAssignedId);

 

        var newUploadBox = document.createElement(“input”);

        var newTextBox = document.createElement(“input”);

        var newDelBtn = document.createElement(“img”);

        var newTypeDdl = document.createElement(“select”);

        var types = <asp:Literal ID=“typesJson1” runat=“server” />;

        for(var t in types) {

            var typ = types[t];

            newTypeDdl.options.add(new Option(typ, typ));

        }

       

        // Set up the new input for file uploads

        newUploadBox.type = “file”;

        newUploadBox.size = “45”;

 

        newTextBox.type = “text”;

        newTextBox.size = “25”;      

 

 newUploadBox.setAttribute(“id”, “File” + addFileUploadBox.lastAssignedId);

 newUploadBox.setAttribute(“name”, “File” + addFileUploadBox.lastAssignedId);

 

 newTextBox.setAttribute(“id”, “Text” + addFileUploadBox.lastAssignedId);

 newTextBox.setAttribute(“name”, “Text” + addFileUploadBox.lastAssignedId);

 newTextBox.style.marginLeft = “8px”;

       

 newTypeDdl.setAttribute(“id”, “Select” + addFileUploadBox.lastAssignedId);

 newTypeDdl.setAttribute(“name”, “Select” + addFileUploadBox.lastAssignedId);

 newTypeDdl.style.marginLeft = “8px”;

 

 newDelBtn.setAttribute(“id”, “img” + addFileUploadBox.lastAssignedId);

 newDelBtn.src = “/cancel.png”;

    

 newDelBtn.style.marginLeft = “4px”;

 newDelBtn.onclick = function() { RemoveUploadBox(this.id) };

 

 container.appendChild(newUploadBox);

 container.appendChild(newTextBox); 

 container.appendChild(newTypeDdl);

 container.appendChild(newDelBtn);

 uploadArea.appendChild(container);

 addFileUploadBox.lastAssignedId++;  }

You can Create a html element using  

var newUploadBox = document.createElement(“input”);

then u can Assign a type to that element like     

      newUploadBox.type = “file”; //It can be Text, or Button or Else.

Then Using SetAttribute method you can assign a name and ID to that control.

We can assign the ID and Name either this way also

      newUploadBox.ID = “SomeID”; newUploadBox.name = “SomeName”;

 

Then you can even create a click event for a button,link or to any control.

 

This is the Tricky Part I have faced when I created this control.

 

If you use the setattribute method to create a link it will work in both FireFox, Chrome and Safari. IE wont recognise that attribute.

After an Intense Google Search I found that if it has to work in IE we need to assign that attribute in the following way.

newDelBtn.onclick = function() { RemoveUploadBox(this.id) };

 

Then On the button Cancel(image) Click We will call this function.

 

    function RemoveUploadBox(id) {

        var str;

        str = id.substring(3);

        var Container = document.getElementById(“Div” + str);

        Container.removeChild(document.getElementById(id));

        Container.removeChild(document.getElementById(“File” + str));

        Container.removeChild(document.getElementById(“Text” + str));

        var uploadArea = document.getElementById(“upload-area”);

        uploadArea.removeChild(Container);

    }

 

This Fucntion takes the the Id of that Cancel button and from there I splitted the ID to find which row we need to remove.

 

So With this USER can add or remove a file dynamically. Then Next Part is Uploading. I have created an EventHandler to handle this upload event in the main page where this control loaded.

 

        public event EventHandler uploadClick;

        protected void btnUpload_Click(object sender, EventArgs e)

        {

            if (uploadClick != null)

            {

                uploadClick(sender, e);

            }

  }

I guess Every thing is straight forward in the above code. I guess some people Don’t know why we need to write this piece of line

if (uploadClick != null)

We must write this line because If the user forgets to write an event for the button click in the main page , and if he clicks upload button in the user control It will give you a null reference Exception.  So If we write this line first it will check whether user raised uploadClick event in the main page or not If he raises then it will do some action or else it wont send the request to main page.

Coming to Main page The code is as follows in aspx Page.

 

<uc1:FileUploadControl ID=”FileUploadControl1″ OnuploadClick=”Upload_Click” runat=”server” />

 

You can see I have raised the event “OnuploadClick”.  In the Code behind in the page load event I checking whether the destination directory exists or not. If it not exists I am creating the directory.

 

        protected void Page_Load(object sender, EventArgs e)

        {

            String UpPath;

            UpPath = “C:\temp”;

 

            if (!Directory.Exists(UpPath))

            {

                Directory.CreateDirectory(“C:\temp\”);

            }

        }

When User Clicks Upload button in the User control it will check whether there is an event raised in the main page or not , if raised it will send the request to main page where user control was placed.

The Code is as follows..

 

     protected void Upload_Click(object sender, EventArgs e)

        {

            HttpFileCollection uploads = HttpContext.Current.Request.Files;

            for (int i = 0; i < uploads.Count; i++)

            {

                HttpPostedFile upload = uploads[i];

 

                if (upload.ContentLength == 0)

                    continue;

 

                try

                {

                    //Retrieving the fullpath of the File.

             string SourceFileName = Path.GetFileName(upload.FileName);

 

                    //Saving it in temperory Directory.

                    upload.SaveAs(“c:\temp\” + SourceFileName);

 

                    //Retrieving HTML TextBox Value using C#

              string Description = Request.Form[“Text” + (i + 1).ToString()];

 

                    //Retrieving HTML Select Value using C#

                  string Type = Request.Form[“Select” + (i + 1).ToString()];

 

                }

                catch

                {

                }

            }

        }

 

Comments are Highly Appreciated. Happy Coding.

 

Thanks,

DotnetRuler 🙂

Keep Rocking as Always m/

Posted in ASP.NET, JavaScript | Tagged: , | 9 Comments »