Tuesday, 19 February 2013

ASP.NET: Display GridView Row Details in Modal Popup using Twitter Bootstrap

There are several ways in which you can display details of a gridview row in order for the user to have a quick overview of the complete row. Especially when there are lot of columns in the gridview the user may find it difficult to scroll the page and view the details of entire row. This is why we have a control called 'DetailsView', a data-bound control that can be used to display single record at a time. There are many options to do this such as displaying details in a tooltip on mouseover event using jQuery, using AJAX ModalPopupExtender on click event etc. A more simple yet efficient approach is to display details of a gridview row in a modal popup dialog using Twitter Bootstrap's Modals plugin.



Steps to Follow,

1. Download bootstrap files from here.

2. Include the latest jQuery library, bootstrap files (bootstrap.js,bootstrap.css) from the download and use below html code in .aspx page.
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>Modal Popup using Bootstrap</title>
    <link href="Styles/bootstrap.css" rel="stylesheet" type="text/css" />
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script src="Scripts/bootstrap.js" type="text/javascript"></script>

</head>
<body>
    <form id="form1" runat="server">
    <div>
    <asp:ScriptManager ID="ScriptManager1" runat="server" />
    <asp:UpdatePanel ID="UpdatePanel1" runat="server">
        <ContentTemplate>
            <div>
            <h2 style="text-align:center;">
                   Display GridView Row Details in Modal Dialog using Twitter Bootstrap</h2>
            <p style="text-align:center;">
                   Demo by Priya Darshini - Tutorial @ <a href="">Programmingfree</a>
            </p>                     
               <asp:GridView ID="GridView1" runat="server" 
                        Width="940px"  HorizontalAlign="Center"
                        OnRowCommand="GridView1_RowCommand" 
                        AutoGenerateColumns="false"   AllowPaging="false"
                        DataKeyNames="Code" 
                        CssClass="table table-hover table-striped">
                <Columns>
                   <asp:ButtonField CommandName="detail" 
                         ControlStyle-CssClass="btn btn-info" ButtonType="Button" 
                         Text="Detail" HeaderText="Detailed View"/>
            <asp:BoundField DataField="Code" HeaderText="Code" />
            <asp:BoundField DataField="Name" HeaderText="Name" />
            <asp:BoundField DataField="Continent" HeaderText="Continent" />
            <asp:BoundField DataField="Region" HeaderText="Surface Area" />
            <asp:BoundField DataField="Population" HeaderText="Population" />
            <asp:BoundField DataField="IndepYear" HeaderText="Year of Independence" />
            <asp:BoundField DataField="LocalName" HeaderText="Local Name" />
            <asp:BoundField DataField="Capital" HeaderText="Capital" />
            <asp:BoundField DataField="HeadOfState" HeaderText="Head of State" />
               </Columns>
               </asp:GridView>
            </div>
        </ContentTemplate>
    </asp:UpdatePanel>
    <asp:UpdateProgress ID="UpdateProgress1" runat="server">
        <ProgressTemplate>
            <br />
        <img src="" alt="Loading.. Please wait!"/>
        </ProgressTemplate>
    </asp:UpdateProgress>
    <div id="currentdetail" class="modal hide fade" 
               tabindex=-1 role="dialog" aria-labelledby="myModalLabel" 
               aria-hidden="true">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" 
                  aria-hidden="true">×</button>
            <h3 id="myModalLabel">Detailed View</h3>
       </div>
   <div class="modal-body">
        <asp:UpdatePanel ID="UpdatePanel2" runat="server">
            <ContentTemplate>
                    <asp:DetailsView ID="DetailsView1" runat="server" 
                              CssClass="table table-bordered table-hover" 
                               BackColor="White" ForeColor="Black"
                               FieldHeaderStyle-Wrap="false" 
                               FieldHeaderStyle-Font-Bold="true"  
                               FieldHeaderStyle-BackColor="LavenderBlush" 
                               FieldHeaderStyle-ForeColor="Black"
                               BorderStyle="Groove" AutoGenerateRows="False">
                        <Fields>
                 <asp:BoundField DataField="Code" HeaderText="Code" />
                 <asp:BoundField DataField="Name" HeaderText="Name" />
                 <asp:BoundField DataField="Continent" HeaderText="Continent" />
                 <asp:BoundField DataField="Region" HeaderText="Surface Area" />
                 <asp:BoundField DataField="Population" HeaderText="Population" />
                 <asp:BoundField DataField="IndepYear" HeaderText="Year of Independence" />
                 <asp:BoundField DataField="LocalName" HeaderText="Local Name" />
                 <asp:BoundField DataField="Capital" HeaderText="Capital" />
                 <asp:BoundField DataField="HeadOfState" HeaderText="Head of State" />
                       </Fields>
                  </asp:DetailsView>
           </ContentTemplate>
           <Triggers>
               <asp:AsyncPostBackTrigger ControlID="GridView1"  EventName="RowCommand" />  
           </Triggers>
           </asp:UpdatePanel>
                <div class="modal-footer">
                    <button class="btn btn-info" data-dismiss="modal" 
                            aria-hidden="true">Close</button>
                </div>
            </div>
    </div>
    </div>
    </form>
</body>
</html>

In the above code, I have used a gridview and detailsview. To open detailsview in modal popup on button click, detailsview is placed inside a div with class='modal'.

3. In code-behind page use the below code. Here I am populating gridview with values from mysql table and using linq query to populate detailsview.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
using MySql.Data.MySqlClient;

namespace DetailModalExample
{
    public partial class Default : System.Web.UI.Page
    {
        DataTable dt;
        protected void Page_Load(object sender, EventArgs e)
        {            
                try
                {
                    //Fetch data from mysql database
                    MySqlConnection conn = new MySqlConnection("server=localhost;uid=root;
                         password=priya123;database=world;pooling=false;");
                    conn.Open();
                    string cmd = "select * from country limit 7";
                    MySqlDataAdapter dAdapter = new MySqlDataAdapter(cmd, conn);
                    DataSet ds = new DataSet();
                    dAdapter.Fill(ds);
                    dt=ds.Tables[0];
                    //Bind the fetched data to gridview
                    GridView1.DataSource = dt;
                    GridView1.DataBind();
                }
                catch (MySqlException ex)
                {
                    System.Console.Error.Write(ex.Message);
                
                }                              
        }
   
        protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
        {
            if(e.CommandName.Equals("detail"))
            {
                int index = Convert.ToInt32(e.CommandArgument);
                string code = GridView1.DataKeys[index].Value.ToString();
                
                    IEnumerable<DataRow> query = from i in dt.AsEnumerable()
                                      where i.Field<String>("Code").Equals(code)
                                       select i;
                    DataTable detailTable = query.CopyToDataTable<DataRow>();
                    DetailsView1.DataSource = detailTable;
                    DetailsView1.DataBind();
                    System.Text.StringBuilder sb = new System.Text.StringBuilder();
                    sb.Append(@"<script type='text/javascript'>");
                    sb.Append("$('#currentdetail').modal('show');");
                    sb.Append(@"</script>");
                    ScriptManager.RegisterClientScriptBlock(this, this.GetType(), 
                               "ModalScript", sb.ToString(), false);

            }
        }
    }
}

Note in the above code I am opening the div containing details view in modal popup using single line of jQuery code,

$('#currentdetail').modal('show');

That is all, now clicking the button field in gridview row will open a modal popup that consists of detailsview populated with the corresponding row data. See live demo. (I have created this demo using simple html table and the output will be the same in asp.net page.)


Please leave your comments and queries about this post in the comment sections in order for me to improve my writing skills and to showcase more useful posts. Thanks for reading!!




Subscribe to GET LATEST ARTICLES!


Most Shared - Last Week


26 comments:

  1. yet again a great demo and work priya... keep rocking :-)

    ReplyDelete
    Replies
    1. Thanks amar! Sure I will try my best!

      Delete
  2. Wow....its so aw some,waiting for the print option desperately in the model pop up...

    ReplyDelete
    Replies
    1. Hi Zakariya,

      Is the print option you are looking for, to print contents of a gridview row that is shown in the modal pop up?

      Thanks,
      Priya

      Delete
  3. Hi Priya,
    I was trying a lot of options to style the ASP.Net GridView Pager contorl but was not successful. Can you help me with the same.

    ReplyDelete
    Replies
    1. Hi Sonu,

      Did you have a chance to look at this?

      http://www.dotnetcurry.com/ShowArticle.aspx?ID=244

      By the way, what kind of styling do you exactly want to have on your gridview pager. Can you show an example?

      Thanks,
      Priya

      Delete
    2. Hi Priya,
      Have look at that but was not successful. some example is pager style I am looking at is http://cssdeck.com/labs/twitter-bootstrap-pagination-and-pager.

      Regards,
      Sonu

      Delete
  4. thanks a lot dear friend lovely example

    ReplyDelete
  5. I can't Make it work i can't see the popup window; i do everything like you say the only difference is that i use Master page in my code and i add all the scripts in the master page .

    ReplyDelete
    Replies
    1. Change your MasterPage script reference to use ResolveUrl() and put your script inside the ContentPlaceHolder being used as follows:

      <script src='<%= Page.ResolveUrl("~/jquery-1.6.2.min.js")' type="text/javascript"></script>

      Hope this helps!

      Delete
  6. Hello - thanks for the tutorial - very good!

    But I am having an issue where clicking the Detail button just refreshes the page - it adds the sb.tostring in the script tags - but nothing actually happens and it just refreshes the page?

    using master page and put references in contentplaceholder on the page using the site.master tried in ie. chrome, firefox too.

    Any suggestions you have would e greatly appreciated?

    ReplyDelete
    Replies
    1. Please check whether the javascript files are referenced properly. This is definitely reference issue and can be solved with a quick googling on 'reference javasript files included in master page'. If this still does not resolve your issue, please post your code snippet and I will try to debug it.

      Thanks,
      Priya

      Delete
  7. Hello

    i am referencing the js files within the content page and not the master page.

    I reference another js file in the content page in the same way which does a filter on a gridview as the user types into the text box,which works fine.

    Cheers

    ReplyDelete
  8. Hello I manage to get it working - sort of..

    For whatever reason the target attribute specified in the updatepanel2 was not liked in my vb.net 2010 website. saying controlid XYZ was not found for trigger in updatepanel updatePanel2

    so I did some research on internet and found that it was needed to be added after load complete etc.. which I did and it did not work..

    SO. I then put this same code into the same function that populates the gridview from my wcf webservice (populategrid sub is called in the page load event)

    and then it WORKED!!!! however, it only works for the first button click, then if another button is clicked, it refreshes the page, then allows you to click once again, then refresh, then click etc etc.

    Any ideas what that could be?

    Thanks in advance :)

    ReplyDelete
  9. Pls, I am a beginner of asp.net developer, i uses VB.Net i really need the script to call bootstrap modal from a asp.net button but all try yeild no reason, pls can you help me, maybe 1. You can help me with simple calling of the bootstrap modal from a asp.net button or send the sample code of this project to me my email is atplerry@gmail, atplerry@yahoo.com. I really appreciate your help Thanks.

    ReplyDelete
  10. Thank for the tutorial. An easy, but very useful way to give a nice touch to my project. Thumbs up for you

    ReplyDelete
  11. This comment has been removed by the author.

    ReplyDelete
    Replies
    1. This comment has been removed by the author.

      Delete