Showing posts with label ItemTemplate. Show all posts
Showing posts with label ItemTemplate. Show all posts

Thursday, June 14, 2012

How to maintain selected Checkboxes state while paging in GridView?


This is common problem- When we implement paging in GridView then it doesn't maintain selected record when you change page index in GridView.
 

Workaround-   

To solve this problem, we can maintain selected records using ViewState variable and after rebinding Grid we can again make those checkboxes selected. For this we have to maintain code in OnCheckedChanged() and PageIndexChanging() events. 

Here I am explaining - How to maintain selected Check-boxes state while paging in GridView?
 

In this example, I have taken one ViewState["SelectedRows"] variable and one List<string> variable. The purpose of using ViewState["SelectedRows"] variable in this example is that- to maintain selected values in GridView.

There are 2 main steps for this task-

1. While selecting value in GridView, I am string those values in View State variable
2. After rebinding GridView, I am  getting selected values from View State variable and setting in GridView.

Here is code-
 

.aspx code-
 
<table>
            <tr>
                <td>
                    <asp:GridView ID="GridEmpData" runat="server" AutoGenerateColumns="false" Width="300px"
                        AllowPaging="True" PageSize="5" OnPageIndexChanging="GridEmpData_PageIndexChanging">
                        <Columns>
                            <asp:TemplateField HeaderText="Select">
                                <ItemTemplate>
                                    <asp:CheckBox ID="chkEmp" runat="server" OnCheckedChanged="chkEmp_OnCheckedChanged" />
                                </ItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="Emp Id">
                                <ItemTemplate>
                                    <asp:Label ID="lblEmpId" runat="server" Text='<%# Eval("id") %>'></asp:Label>
                                </ItemTemplate>
                            </asp:TemplateField>
                            <asp:TemplateField HeaderText="Emp Name">
                                <ItemTemplate>
                                    <asp:Label ID="lblEmpName" runat="server" Text='<%# Eval("name") %>'> </asp:Label>
                                </ItemTemplate>
                            </asp:TemplateField>
                        </Columns>
                    </asp:GridView>
                </td>
            </tr>
        </table>

 
 I have taken one CheckBox inside ItemTemplate of GridView, using this CheckBox records will be selected. I have bounded one server side event to this CheckBox - chkEmp_OnCheckedChanged().
In this event I have written code to store selected record in View State Variable.

The output of this page will be-


Maintaining selected Checkboxes state while paging


Now .cs code-

 
 protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            //Loading data to Grid
            GetData();
        }
    }

    protected void chkInactivate_OnCheckedChanged(object sender, EventArgs e)
    {
        CheckBox chkStatus = (CheckBox)sender;
        GridViewRow selectedrow = (GridViewRow)chkStatus.NamingContainer;

        //Getting selected records from View state
        List<string> selectedItems = null;
        if (ViewState["SelectedRows"] != null)
        {
            selectedItems = (List<string>)ViewState["SelectedRows"];
        }
        else
        {
            selectedItems = new List<string>();
        }

        Label lblEmpId = (Label)selectedrow.FindControl("lblEmpId");

        //If checked then adding to list
        if (chkStatus.Checked)
        {

            selectedItems.Add(lblEmpId.Text);
        }
        //if unchecked then remove from list if exist
        else
        {
            var result = selectedItems.Find(item => item == lblEmpId.Text);

            if (result != null)
            {
                selectedItems.Remove(lblEmpId.Text);
            }
        }

        //Assigning Selected records to ViewState
        ViewState["SelectedRows"] = selectedItems;
    }

    //Function to Fill Grid
    private void GetData()
    {
        try
        {
            SqlConnection cn = new SqlConnection("connection string");
            cn.Open();
            DataSet ds = new DataSet();
            SqlDataAdapter da = new SqlDataAdapter("select id,name  from tablename", cn);
            da.Fill(ds);
            GridEmpData.DataSource = ds;
            GridEmpData.DataBind();
        }
        catch (Exception)
        { 
            throw;
        }
    
    }

    protected void GridEmpData_PageIndexChanging(object sender, GridViewPageEventArgs e)
    {
        GridEmpData.PageIndex = e.NewPageIndex;
      
        //Loading data to Grid
        GetData();

        //Code to maintain selected record while paging
        if (ViewState["SelectedRows"] != null)
        {
            List<string> selectedItems = (List<string>)ViewState["SelectedRows"];
            foreach (GridViewRow row in GridEmpData.Rows)
            {
                Label lblEmpId = (Label)row.FindControl("lblEmpId");
                var result = selectedItems.Find(item => item == lblEmpId.Text);
                if (result != null)
                {
                    CheckBox chk = (CheckBox)row.FindControl("chkEmp");
                    if (chk != null)
                    {
                        chk.Checked = true;
                    }
                }
            }
        }
    }
 


In above code, First I am binding GridView using GetData() function in page_Load() event.

In OnCheckedChanged() event of CheckBox, first I am getting selected record from View State variable, and after that I am adding newly selected record into View State variable. Suppose if any record is already present then I am removing from View State variable, For this operation I am using List<string>, using List<string> records are adding  and deleting.Finally I am assigning List<string> variable to ViewState.

In PageIndexChanging () event, I have written logic for GridView paging, Here I am setting new page index for paging in GridView. In this event only after rebinding GridView, I am getting selected record from View State variable and assign to GridVIew.


Note- It you want to prevent postback then you can make use of AJAX, for this put your GridView inside the UpdatePanel.




Thanks


Monday, June 11, 2012

Downloading file using GridView in Asp.Net.



In some of the cases we want to give file listing with download option. Here I am explaining, How to download file using GridView in Asp.Net?

For this task, I have created my Database table like this-
FileDetails(FileId,FileName,FilePath)


Here-

FileId -  Auto generated filed, to maintain primary key for file
FileName - Name of Uploaded file
FilePath - Complete file path for uploaded file
 

In this example, I am designing GridView with three columns, Here FileId and FilePath will be invisible mode, FileName will be displayed to the user. based on user action FileId and FilePath will be fetched from GridView and these values will be used for further processing.  
 

.aspx code-

 <asp:GridView ID="grdFileDetails" runat="server" AutoGenerateColumns="false" OnRowCommand="grdFileDetails_RowCommand">
        <EmptyDataTemplate>
            <div style="color: Red; text-align: center; width: 700px">
                No Data Found.
            </div>
        </EmptyDataTemplate>
        <Columns>
            <asp:TemplateField HeaderText="File ID" ItemStyle-HorizontalAlign="Left">
                <ItemTemplate>
                    <asp:Label ID="lblFileId" runat="server" Text='<%# Eval("FileId") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="File Name" ItemStyle-HorizontalAlign="Left">
                <ItemTemplate>
                    <asp:Label ID="lblFileName" runat="server" Text='<%# Eval("FileName") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="File Path" Visible="false">
                <ItemTemplate>
                    <asp:Label ID="lblFilePath" runat="server" Text='<%# Eval("FilePath") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
            <asp:TemplateField HeaderText="Download">
                <ItemTemplate>
                    <asp:Button ID="btnDownLoad" runat="server" Text="Download" CommandName="download"  CommandArgument='<%# Eval("FilePath") %>' />
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

 
In above code, I have taken 4 columns in GridView, but here File ID and File Path is hidden, I am not showing File Path and File ID. I am passing FilePath value using CommandArgument property, this value will be used in server side code to download file. For button I have set CommandName= "download" so that button click can be handled in RowCommand() event of GridView.

        <ItemTemplate>
            <asp:Button ID="btnDownLoad" runat="server" Text="Download" CommandName="download"  CommandArgument='<%# Eval("FilePath") %>' />
        </ItemTemplate>

 

The output of this .aspx will be -

Downloading file using GridView.

Now .cs code-

 protected void grdFileDetails_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            try
            {
                //Code to download file
                if (e.CommandName == "download")
                {
                    string filepath = Convert.ToString(e.CommandArgument);

                    byte[] data = System.IO.File.ReadAllBytes(filepath);
                    Response.Clear();
                    Response.ClearHeaders();
                    Response.AddHeader("Content-Type", "Application/octet-stream");
                    Response.AddHeader("Content-Length", data.Length.ToString());
                    Response.AddHeader("Content-Disposition", "attachment; filename=" + filepath);
                    Response.BinaryWrite(data);
                    Response.End();
                }

            }

            catch (Exception)
            {
                 throw;
            }
        }


In above code, I have implemented GridVIew_RowCommand() event , here first I am checking commandName value using e.CommandName.

To get particular file path here I am using e.CommandArgument like this-

   string filepath = Convert.ToString(e.CommandArgument);

 After getting File path I have used Response object to download file like this-
 
   Response.BinaryWrite(data);
 
Here data will contain binary data that will be downloaded as a file. Before download the file it is must that we have to set some settings using Response.AddHeader() method. Here we have to set Content-Type and  Content-Length for downloading object.  Now if you will click on download button then related file will be downloaded.

Thanks

Friday, December 30, 2011

Accessing GridView controls using Client side code/ Jquery


Accessing GridView controls from server side is such a easy task, but when we access GridView controls from client side then generally we face problem, because if we use getElementById() to get GridView controls then it creates complexity.

In this article, I am going to explain – How you can access GridView controls from client side?  By using this method not only you can access single control but also you can access more than one control with single line of code.

In this example, I am using Jquery. Here I am accessing GridView control (LinkButton) and hiding/showing that control from client side.

First, I have defined one blank CSS class - clsFind

<style type ="text/css">
    .clsFind
    {
    }
</style>


Note-  


Using this CSS class only, we will access GridView Control.

Now I have defined these two functions to get GridView control (LinkButton) and after that I am hiding/ showing that control.

<script type ="text/javascript" >
    //Function to Hide control
    function HideControl() {
        var con = $(".clsFind");
        con.hide();
        return false;
    }

    //Function to Show control
    function ShowControl() {
        var con = $(".clsFind");
        con.show();
        return false;
    }
    </script>


Note-

 
HideControl function will be called when you will press Hide Control Button.
ShowControl function will be called when you will press Show Control Button.

Now I have designed GridView like this-



GridView

Here is .aspx code-

 
<asp:GridView ID="GrdEmpData" runat="server" AutoGenerateColumns="false"
                onrowdeleting="GrdEmpData_RowDeleting" Width ="50%">
                <Columns>
                    <asp:TemplateField HeaderText="EmpId" ItemStyle-HorizontalAlign  ="Left"  ItemStyle-Width ="20%">
                        <ItemTemplate>
                            <asp:Label ID="lblEmpId" runat="server" Text='<% # Eval("EmpId") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="EmpName" ItemStyle-HorizontalAlign  ="Left"  ItemStyle-Width ="30%">
                        <ItemTemplate>
                            <asp:Label ID="lblEmpName" runat="server" Text='<% # Eval("EmpName") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField HeaderText="DeptId" ItemStyle-HorizontalAlign  ="Left"  ItemStyle-Width ="30%">
                        <ItemTemplate>
                            <asp:Label ID="lblDeptName" runat="server" Text='<% # Eval("DeptName") %>'></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>
                    <asp:TemplateField  HeaderText="Delete" ItemStyle-HorizontalAlign  ="Left"  ItemStyle-Width ="20%">
                        <ItemTemplate>
                            <asp:LinkButton ID="lnkDelete" runat="server" Text="Delete" CommandName ="delete" CssClass  ="clsFind"></asp:LinkButton>
                        </ItemTemplate>
                    </asp:TemplateField>
                </Columns>
            </asp:GridView>
            <br />
        <asp:Button ID="btnShowControl" runat="server" Text="Show Delete Button" OnClientClick ="return ShowControl();"/>
        <asp:Button ID="btnHideControl" runat="server" Text="Hide Delete Button" OnClientClick="return HideControl();" />


Now done, when you will press Hide Control Button then delete LinkButton will be disappeared, and your GridView will be like this-



Hiding Control in GridView


To show LinkButton again, you can press Show Control Button.

Note-

 
The main advantage of this approach is that, you can access more than one controls using single line of code. For that,  you have to code like this-

 <asp:LinkButton ID="lnkDelete" runat="server" Text="Delete" CommandName ="delete" CssClass  ="clsFind"></asp:LinkButton>

 <asp:LinkButton ID="lnkShow" runat="server" Text="show"  CssClass ="clsFind"></asp:LinkButton>

 
Means, you have to give same CSS class for controls. Now when you will use this statement –

 var con = $(".clsFind");

Then using "con" object only, you can set properties for lnkDelete and lnkEdit  LinkButtons. Like this-


  con.hide();

This approach is useful when we have multiple controls and we want to set same type of values for their properties.


Update  :

To get control value :


Suppose you have LinkButton inside GridView with Text "Delete"

<asp:TemplateField HeaderText="Delete" ItemStyle-HorizontalAlign="Left" ItemStyle-Width="20%">
  <ItemTemplate>
      <asp:LinkButton ID="lnkDelete" runat="server" Text="Delete"  CommandName="delete"  CssClass="clsFind"></asp:LinkButton>
   </ItemTemplate>
</asp:TemplateField>


Now to get control value, We have one button outside of the GridVIew


 <asp:Button ID="btnGetValue" runat="server" Text="Get Value" OnClientClick="return GetValue();" />


Use these code to get value-

 <script type="text/javascript">

    //Function to get control value

        function GetValue() {
            var con = $(".clsFind");
           
  // Way 1:To get combine text of all link button in GridView
            var combineText = con.text()
            alert(combineText);


  //Way 2: To get text of any particular link button in GridView (for first row)
            var firstRowLinkButtonText1 = con[0].innerHTML
            alert(firstRowLinkButtonText );


  //Way 3: To get text of any particular link button in GridView (for first row)

            var firstRowLinkButtonText2 = $('#GrdEmpData tr>td>a[id*=lnkDelete]')[0].innerHTML;
            alert(firstRowLinkButtonText2);
 
            return false;
        }
   
    </script>




Try these way and let me know.

 

Thanks