GridView Grouping Master/Detail Drill Down using AJAX and jQuery

by mosessaur| 19 April 2008| 96 Comments

Introduction:
Last month I posted about Building a grouping Grid with GridView and JQuery. And I got feedbacks about how to do the same thing using AJAX (on demand retrieving of detail data). In fact I was thinking of that too, and I had couple of ideas in mind. One of them it to use nested update panels, or use AJAX Data Controls with page method/web service method calls along with ASP.NET AJAX. You can view the [demo here].

I didn't like the nested update panel idea, although it is the easiest I think. And was started to think about the second idea but I was about to check another way other than ASP.NET AJAX as long as I'm using jQuery. So I was thinking of using jQuery AJAX. That was just after reading Dave Ward's post Using jQuery to consume ASP.NET JSON Web Services.

GridViewDrillDownJQueryAjax00  GridViewDrillDownJQueryAjax01

Prerequisites:
I recommend to read Dave's post Using jQuery to consume ASP.NET JSON Web Services before you proceed. And not only the post but also the comments, because the post itself contains the core information while the comments contain issues with resolutions. And myself I used one of the techniques discussed on the post's comments which is Page Method calls using jQuery AJAX. Another post I wish you to read also from Dave's blogwhich is Why do ASP.NET AJAX page methods have to be static?. Also Dave posted about Using jQuery to directly call ASP.NET AJAX page methods. You may wish to review the above posts first.

Implementation:
I modified the sample I provided in my post Building a grouping Grid with GridView and jQuery to apply the new technique I provide here. Simply when the user click on the master (Customer name) the details (Customer Orders) are populated on demaned and displayed underneath on a sliding DIV using jQuery.

I didn't build web service to retrieve the data instead I used a Page Method. Also I used a technique Dave used in his sample. So I'll start from this point. I'll explore the Page Method along with the technique used to retrieve the data.

I built a User Control that is responsible for retireving and displaying the detail data (Customer Order). The user control only contain a SqlDataSource and Repeater control:

   1: <asp:SqlDataSource ID="sqlDsOrders" runat="server" ConnectionString="<%$ ConnectionStrings:Northwind %>"
   2:     SelectCommand="SELECT [OrderID], [OrderDate], [RequiredDate], [Freight], [ShippedDate] FROM [Orders] WHERE ([CustomerID] = @CustomerID)">
   3:     <SelectParameters>
   4:         <asp:Parameter Name="CustomerID" Type="String" DefaultValue="" />
   5:     </SelectParameters>
   6: </asp:SqlDataSource>
   7: <asp:Repeater ID="List" DataSourceID="sqlDsOrders" runat="server">
   8:     <HeaderTemplate>
   9:         <table class="grid" cellspacing="0" rules="all" border="1" style="border-collapse: collapse;">
  10:             <tr>
  11:                 <th scope="col">&nbsp;</th>
  12:                 <th scope="col">Order ID</th>
  13:                 <th scope="col">Date Ordered</th>
  14:                 <th scope="col">Date Required</th>
  15:                 <th scope="col" style="text-align: right;">Freight</th>
  16:                 <th scope="col">Date Shipped</th>
  17:             </tr>
  18:     </HeaderTemplate>
  19:     <ItemTemplate>
  20:         <tr class='<%# (Container.ItemIndex%2==0) ? "row" : "altrow" %>'>
  21:             <td class="rownum"><%#Container.ItemIndex+1 %></td>
  22:             <td style="width: 80px;"><%Eval("OrderID") %></td>
  23:             <td style="width: 100px;"><%Eval("OrderDate","{0:dd/MM/yyyy}") %></td>
  24:             <td style="width: 110px;"><%Eval("RequiredDate", "{0:dd/MM/yyyy}")%></td>
  25:             <td style="width: 50px; text-align: right;"><%# Eval("Freight","{0:F2}") %></td>
  26:             <td style="width: 100px;"><%# Eval("ShippedDate", "{0:dd/MM/yyyy}")%></td>
  27:         </tr>
  28:     </ItemTemplate>
  29:     <FooterTemplate>
  30:         </table>
  31:     </FooterTemplate>
  32: </asp:Repeater>

Below is the OnLoad event handler of the User Control:

   1: protected override void OnLoad(EventArgs e)
   2: {
   3:     this.sqlDsOrders.SelectParameters["CustomerID"].DefaultValue = this.CustomerId;
   4:     base.OnLoad(e);
   5: }

I didn't use GridView instead of Repeater because it produced an exception and I didn't investigate much around this issue. Also I'm still using VS.NET 2005 & .Net 2.0 so I didn't yet switch to VS.NET 2008 to use the new features.

As you might notice, the User Control has a property called CustomerId. During the call of the page method, I pass CustomerId to the called mathod which in turn set this property. Now to make the idea fully complete you need to view the Page Method:

   1: [System.Web.Services.WebMethod()]
   2: public static string GetOrders(string customerId)
   3: {
   4:     System.Threading.Thread.Sleep(500);
   5:     Page page = new Page();
   6:     CustomerOrders ctl = (CustomerOrders)page.LoadControl("~/CustomerOrders.ascx");
   7:     ctl.CustomerId = customerId;
   8:     page.Controls.Add(ctl);
   9:     System.IO.StringWriter writer = new System.IO.StringWriter();
  10:     HttpContext.Current.Server.Execute(page, writer, false);
  11:     string output = writer.ToString();
  12:     writer.Close();
  13:     return output;
  14: }

The above code is exactly taken from David's Sample, I just adjust it to suite my requirements of course like passing and setting CustomerId. Simply create new Page Class (IHttpHandler), load the user control add to the page and finally Execuse the page using Server.Execute. This way I didn't need to spend much time prepare the way to display my data because I already have my HTML ready for render.

That was all about the Server Side code. Its time to explore the client side and how AJAX call is initiated. Each item of the Master GridView (Customers) is displayed like this:

   1: <div class="group" style="display:inline" id='<%#String.Format("customer{0}",Container.DataItemIndex) %>' 
   2:     onclick='showhide(<%#String.Format("\"#customer{0}\"",Container.DataItemIndex) %>,
   3:                       <%#String.Format("\"#order{0}\"",Container.DataItemIndex) %>,
   4:                       <%#String.Format("\"{0}\"",Eval("CustomerID")) %>)'>
   5:     <asp:Image ID="imgCollapsible" CssClass="first" ImageUrl="~/Assets/img/plus.png"
   6:         Style="margin-right: 5px;" runat="server" /><span class="header">
   7:             <%#Eval("CustomerID")%>:
   8:             <%#Eval("CompanyName")%>(<%#Eval("TotalOrders")%> Orders) </span>
   9: </div>                                                        
  10: <div id='<%#String.Format("order{0}",Container.DataItemIndex) %>' class="order"></div>

The first DIV is for Master Item (Customer), second DIV is for Detail Items (Orders). When user click on the first DIV, AJAX request is initiated and returned HTML is set for the second DIV then its slided down displaying the detail items.

The first DIV has onclick client event handler called showhide(div1Id,div2Id,customerId). The handler Initiate the AJAX Request and like the following:

   1: $.ajax({
   2:         type: "POST", //POST
   3:         url: "GridViewDrillDownjQueryQAjax.aspx/GetOrders", //Set call to Page Method
   4:         data: params, // Set Method Params
   5:         beforeSend: function(xhr) {
   6:             xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");},
   7:         contentType: "application/json; charset=utf-8", //Set Content-Type
   8:         dataType: "json", // Set return Data Type
   9:         success: function(msg, status) {
  10:             $('#progress').css('visibility','hidden');
  11:             $(master).children()[0].src = src;
  12:             $(detail).html(msg);
  13:             $(detail).slideToggle("normal"); // Succes Callback
  14:             },
  15:         error: function(xhr,msg,e){
  16:             alert(msg);//Error Callback
  17:             }
  18:         });

Because I'm using the same technique explained in Dave's post, there is no much to mention here. However I'm going to explore each parameter passed to the ajax method of jQuery:

  • type: type of the request. I use POST method. return to David's post for more details.
  • url: URL of the distination I issue a request for (Page or Web Service) attached to is method name I want to invoke.
  • data: Data to be sent to the server: '{customerId:"ALFKI"}'. You can also review comments on Dave's post regarding this option or review the documentation.
  • beforeSend: Return to Dave's post for more details or to the jQuery.ajax documentation.
  • contentType: When sending data to the server, use this content-type. Default is "application/x-www-form-urlencoded", which is fine for most cases. I recommend that you checkout Dave's post's comments as it contains resolution for an issue related to IE. As a summary, we use beforeSend to set the content type of the request, for some reasons IE use the default content type still. So we add this option contentType to resolve the issue.
  • dataType: The type of data that you're expecting back from the server. Review documentation and return to Dave's post for more details
  • success: A function to be called if the request succeeds. The function gets passed two arguments: The data returned from the server, formatted according to the 'dataType' parameter, and a string describing the status. I used it to display the sliding DIV and set the returned data to the DIV HTML.
  • error: A function to be called if the request fails. The function gets passed three arguments: The XMLHttpRequest object, a string describing the type of error that occurred and an optional exception object, if one occurred.

The following show the complete JavaScript call for the showhide method:

   1: //master: id of div element that contains the information about master data
   2: //details: id of div element wrapping the details grid
   3: //customerId: id of the customer to be send as parameter to web method
   4: function showhide(master,detail,customerId)
   5: { 
   6:     //First child of master div is the image
   7:     var src = $(master).children()[0].src;
   8:     //Switch image from (+) to (-) or vice versa.
   9:     if(src.endsWith("plus.png"))
  10:         src = src.replace('plus.png','minus.png');
  11:     else
  12:         src = src.replace('minus.png','plus.png');
  13:     //if the detail DIV is empty Initiate AJAX Call, if not that means DIV already populated with data             
  14:     if($(detail).html() == "")
  15:     {
  16:         //Prepare Progress Image
  17:         var $offset = $(master).offset();
  18:         $('#progress').css('visibility','visible');
  19:         $('#progress').css('top',$offset.top);
  20:         $('#progress').css('left',$offset.left+$(master).width());                    
  21:         //Prepare Parameters
  22:         var params = '{customerId:"'+ customerId +'"}';                    
  23:         //Issue AJAX Call
  24:         $.ajax({
  25:                 type: "POST", //POST
  26:                 url: "GridViewDrillDownjQueryQAjax.aspx/GetOrders", //Set call to Page Method
  27:                 data: params, // Set Method Params
  28:                 beforeSend: function(xhr) {
  29:                     xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");},
  30:                 contentType: "application/json; charset=utf-8", //Set Content-Type
  31:                 dataType: "json", // Set return Data Type
  32:                 success: function(msg, status) {
  33:                     $('#progress').css('visibility','hidden');
  34:                     $(master).children()[0].src = src;
  35:                     $(detail).html(msg);
  36:                     $(detail).slideToggle("normal"); // Succes Callback
  37:                     },
  38:                 error: function(xhr,msg,e){
  39:                     alert(msg);//Error Callback
  40:                     }
  41:                 });
  42:     }
  43:     else
  44:     {
  45:         //Toggle expand/collapse                   
  46:         $(detail).slideToggle("normal");
  47:         $(master).children()[0].src = src;
  48:     }
  49: }

NOTE:
There is something I need to mentione here, when I uploaded my sample to my Web Host, I received an error while testing. When I viewed the error using FireBug, I noticed that the Content-Length is not send with the request header and it is mandatory. That never happen in my development environement. So I had to add the following line in the beforeSend function:

xhr.setRequestHeader("Content-length", params.length);

Conclusion:
I didn't need a real Web Service to actually retrieve the data. I thought that using Page Method is just enough and satisfy my needs. I think, not everything should be made as Web Service, my requirements do not specify that the Gustomer Orders should be exposed through a Web Service, specially that I wish to return a formatted HTML fragment in JSON form. So, Page Method was ideal for me.

Everytime I work with jQuery I reliaze how far it is powerful and easy to use. You can download the demo project (62.21 kb) to explore the whole code and view the demo to see how it is work.

I hope you find this post helpful with value.

kick it on DotNetKicks.com

Comments

Stevef
Stevef United Kingdom on 3/18/2008 4:37 PM Not really sure I see the logic in returning html in json, defeats the point of a lightweight response if you bloat it with html tags. Why not just have a simple template html fragment which you copy for each item returned in the ajax response, would be much quicker and response time would be better.
Stevef
Stevef United Kingdom on 3/18/2008 4:39 PM P.S, take a look at the inbuilt getJSON method that jquery has
http://docs.jquery.com/Ajax/jQuery.getJSON
Stevef
Stevef United Kingdom on 3/19/2008 11:26 AM Moses, what did you do with my comments?
mosessaur
mosessaur Egypt on 3/21/2008 7:32 AM Sorry Steve, I just read your comments and they were waiting for approval.
You might be right that this will break the lightweight response which JSON guarantee.
But myself I do trade offs. What is the size of my response?! And where I'm going to use it? It is already not too much and I'm not going to use to render a full page. And is the performance really affected?! It is just a way that can be improved. Thank you for the link. And I would appreciate if you could demonstrate your solution!
Dave
Dave United States on 3/24/2008 9:31 AM This is a great application of the technique, Moses.  Nice work.

@Stevef:  Due to the content-type requirement for ASP.NET JSON requests, jQuery.getJSON unfortunately won't work here.
mosessaur
mosessaur Egypt on 3/25/2008 8:44 AM Thank you Dave, I just used your method to modify my sample.
I read the documentation of jQuery.getJSON too, and yes it won't work for this technique.
soohyung
soohyung United States on 3/27/2008 12:09 AM Can you please show me the one using nested update panel, which is the easist one.
Thanks,
mosessaur
mosessaur Egypt on 3/28/2008 7:35 AM @soohyung sorry for being late to answer, I was on a trip!
Actually I didn't try it myself, as I implemented the way I did here!
Not sure actually if I can provide that soon! but I will try, but I cannot promis
Cristiano
Cristiano Italy on 3/31/2008 4:53 PM I try to run your application but i get the error "Interface not supported" executing "this.appendChild(elem)" in jquery-1.2.3.min.js. What is the problem?
Sorry but i'm new with javascript and jquery.
Thanks
mosessaur
mosessaur Egypt on 4/1/2008 3:03 AM which browser you are using what is its version?!
The sample is tested with IE 7.0, FF 2.0.0.1x, Opera 9.2x and Safari 3.1.1 for Windows! and it is working just fine!
Cristiano
Cristiano Italy on 4/1/2008 5:21 PM I use IE 7.0
mosessaur
mosessaur Egypt on 4/2/2008 4:46 AM Ok did you tried the online demo?! if yes do you face the same issue with it? or only locally?
And could you please test it with FF or Opera, I guess something is disabled on your IE or something is wrong with IE
Walt
Walt United States on 5/19/2008 6:47 AM Hi Moses, thanks for the great example! It's just what I was looking for. One thing I ran into, when you return the data on the $.ajax call, you used $(detail).html(msg); to insert the result into the div. That didn't work for me, and I ended up using $(detail).html(msg.d); (which I got from Dave's great post). What does the ".d" refer to? Thanks again.
mosessaur
mosessaur Egypt on 5/19/2008 9:02 AM I'm not sure what does "d" refers to!! It is true that Dave's post was my first reference, but I returned to the Ajax documentation for jQuery too. And I didn't notice the "d" in Dave's post.
You could as him, Myself will do that to checkout what it the issue with it! how come this don't work with you while it works with me and what does "d" property refers to.
Rainmaker
Rainmaker Taiwan on 5/24/2008 2:39 AM Sir, My user control had a GridView, when call PageMethod HttpContext.Current.Server.Execute(page, writer, false);
I will get the error below,
System.Web.HttpException: Control 'xxx_WidgetGridView1' of type 'GridView' must be placed inside a form tag with runat=server.
Any one can solve it? thanks.
mosessaur
mosessaur Egypt on 5/24/2008 4:25 PM Actually no! Because GridView must be placed inside form tag that is decorated with runat="server"
That is why it is better to use ListView and Repeater
mosessaur
mosessaur Egypt on 6/4/2008 3:25 AM @Walt: Please check Dave response at his blog entry:
encosia.com/.../
MillerTime
MillerTime United States on 6/7/2008 12:53 PM Do you know of a way to get a third level of detail or detail grid or repeater inside your order line?
mosessaur
mosessaur Egypt on 6/8/2008 6:52 PM You mean to display each order detail on the same way?!
Well, I'm this can be done, but maybe need to think of a way to put it live! I'll think about it
Mahendra
Mahendra India on 6/25/2008 6:43 AM Mosa, nice work...
mosessaur
mosessaur Egypt on 6/25/2008 7:12 AM @Mahendra Thank you Smile
trackback
Moses's Blog on 7/16/2008 12:35 AM Trackback from Moses's Blog

Building on demand Master/Detail grouping Grid with GridView and ASP.NET AJAX toolkit CollapsiblePanelExtender
Ahtisam
Ahtisam United Kingdom on 8/6/2008 8:54 PM Hi Mosa nice work ..

I have seen the demo and the score code I really like the way you are doing all this
and I want to impalement some like this in my project, but there are couple of things which are different in my project I have only one default.aspx page in my project and that contains nothing, all the stuff will be define at runtime to generate the whole page with different types of usercontrol.ascx, so I want to call the ajax from usercontrol.ascx which will load another usercontrol.ascx HTML into first one.

Can you help me out with this
King Regards
Muhammad Mosa
Muhammad Mosa Egypt on 8/6/2008 9:01 PM @ Ahtisam Thank you for the comment.
I see this is a bit complicated scenario. Well my idea is to create static page methods in the default.aspx or make a webservice to be used internally by your application. The methods or the webservice will be responsible to load the ASCX files as shown in my example.
Your AJAX code can then reside in your ASCX files. One thing I never tried is to make Page Methods in UserControls, but I think this will not work. So My recommended solution is build an internal webservice to serve your application. I hope that provide you with some help Smile
Ahtisam
Ahtisam United Kingdom on 8/6/2008 9:25 PM That was quick replay ...

Ok then lets do is another way what if I make one more .aspx page on that I will drop the FirstUserControl.ascx and which will call the SecondUserControl.ascx with the .ajax request like you are doing in your DEMO and firstusercontrol.ascx will load all the HTML rather then the .aspx page is that make scene/possible

Regards
Ahtisam
Ahtisam United Kingdom on 8/6/2008 9:28 PM That was quick replay ...

Ok then lets do is another way what if I make one more .aspx page on that I will drop the FirstUserControl.ascx and which will call the SecondUserControl.ascx with the .ajax request and firstusercontrol.ascx will load all the HTML rather then the .aspx page is that make scene/possible.

Regards
mosessaur
mosessaur Egypt on 8/6/2008 9:32 PM @ Ahtisam yup, that should work too. Let me know how is everything moving with you.
Ahtisam
Ahtisam United Kingdom on 8/7/2008 12:12 AM Hi Moses

I am having Error # 403 which I now is for forbidden URL, but I couldn’t find what I am doing wrong here.
I have default.aspx page on the root then I have 2 usercontrols inside Controls folder and the url which I am passing from the firstusercontrol is:

POST
http://localhost:00000/GridViewDrillDownJQueryAjax/controls/ViewUserMusicUI.ascx/GetPlaylistTracks
403 61ms
Can you please help me out what I am doing wrong or am I missing some thing ?

Kind Regards
mosessaur
mosessaur Egypt on 8/7/2008 12:16 AM @ Ahtisam
You cannot do this:
http://localhost:00000/GridViewDrillDownJQueryAjax/controls/ViewUserMusicUI.ascx/GetPlaylistTracks
your request must be directed to ASPX or ASMX or any other processable or executable Handler, not ASCX UserControl.
Don't put your Page Methods in UserControl
Ahtisam
Ahtisam United Kingdom on 8/7/2008 12:25 AM So this means that the URL request should be like this
http://localhost:00000/GridViewDrillDownJQueryAjax/controls/WebService.asmx/GetPlaylistTracks

Right..?
mosessaur
mosessaur Egypt on 8/7/2008 12:37 AM @Ahtisam Yes, but you have to have WebService.asmx in your web site. Or you can make a static page method in your Default.aspx and in this case your URL will be http://localhost:00000/GridViewDrillDownJQueryAjax/controls/Default.aspx/GetPlaylistTracks
Ahtisam
Ahtisam United Kingdom on 8/7/2008 1:24 AM Hi again and thanks worked in page method and one last thing i am send you the code which is working fine in page method but not in webservice.cs


[System.Web.Services.WebMethod()]
    public static string GetOrders(string CustomerOrder)
    {
        System.Threading.Thread.Sleep(500);
        Page page = new Page();
        CustomerOrder ctl = (CustomerOrder)page.LoadControl("~/controls/CustomerOrder.ascx");
        ctl.CustomerOrder = CustomerOrder;
        page.Controls.Add(ctl);
        System.IO.StringWriter writer = new System.IO.StringWriter();
        HttpContext.Current.Server.Execute(page, writer, false);
        string output = writer.ToString();
        writer.Close();
        return output;
    }

can u please tell me what is wrong!
b/c I have never used the webservice before so this is new for me and quite interesting as well

Regards
mosessaur
mosessaur Egypt on 8/7/2008 1:28 AM @Ahtisam For WebService you don't need to mark the method as Static. So remove static keyword from method declaration. This should make it work.
Ahtisam
Ahtisam United Kingdom on 8/7/2008 1:34 AM [System.Web.Services.WebMethod()]
    public string GetOrders(string CustomerOrder)
    {
        System.Threading.Thread.Sleep(500);
        Page page = new Page();
        CustomerOrder ctl = (CustomerOrder)page.LoadControl("~/controls/CustomerOrder.ascx");
        ctl.CustomerOrder = CustomerOrder;
        page.Controls.Add(ctl);
        System.IO.StringWriter writer = new System.IO.StringWriter();
        HttpContext.Current.Server.Execute(page, writer, false);
        string output = writer.ToString();
        writer.Close();
        return output;
    }
========================
Still sending Error 500
========================
function showhide(master,detail,customerId)
            {
                //First child of master div is the image
                var src = $(master).children()[0].src;
                //Switch image from (+) to (-) or vice versa.
                if(src.endsWith("plus.png"))
                    src = src.replace('plus.png','minus.png');
                else
                    src = src.replace('minus.png','plus.png');
                //if the detail DIV is empty Initiate AJAX Call, if not that means DIV already populated with data            
                if($(detail).html() == "")
                {
                    //Prepare Progress Image
                    var $offset = $(master).offset();
                    $('#progress').css('visibility','visible');
                    $('#progress').css('top',$offset.top);
                    $('#progress').css('left',$offset.left+$(master).width());                    
                    //Prepare Parameters
                    var params = '{customerId:"'+ customerId +'"}';                    
                    //Issue AJAX Call
                    $.ajax({
                            type: "POST", //POST
                            url: "WebService.asmx/GetOrders", //Set call to Page Method
                            data: params, // Set Method Params
                            beforeSend: function(xhr) {
                                xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");},
                            contentType: "application/json; charset=utf-8", //Set Content-Type
                            dataType: "json", // Set return Data Type
                            success: function(msg, status) {
                                $('#progress').css('visibility','hidden');
                                $(master).children()[0].src = src;
                                $(detail).html(msg);
                                $(detail).slideToggle("normal"); // Succes Callback
                                },
                            error: function(xhr,msg,e){
                                $('#progress').css('visibility','hidden');
                                alert(msg);//Error Callback
                                }
                            });
                }
                else
                {
                    //Toggle expand/collapse                  
                    $(detail).slideToggle("normal");
                    $(master).children()[0].src = src;
                }
            }

mosessaur
mosessaur Egypt on 8/7/2008 1:39 AM @Ahtisam Could you please debug and check if the method is being invoked or not?!
I should tried it myself, but I am busy right now. I'll check it and get back to you
Ahtisam
Ahtisam United Kingdom on 8/7/2008 1:43 AM ok

this js code works fine for the page method but didn't invoked on webservice.asmx call

you'll have a look

Regards  
Ahtisam
Ahtisam United Kingdom on 8/7/2008 5:38 AM
Hi Moses
thanks for all your help
I figure out what was wrong it's just this [var params = '{customerId:"'+ customerId +'"}'; ]line in JS which should be like this [var params = "{'customerId':'"+ customerId +"'}"; ]

And now every thing is working fine.

Thanks once again
keep up the Good work ;)
Best Regards
mosessaur
mosessaur Egypt on 8/7/2008 5:40 AM @Ahtisam Thank you man for letting me know. I hope you liked it and that it works fine with you now.
Cheers
Rainmaker
Rainmaker Taiwan on 8/10/2008 8:14 PM Hi Moses,
  It's possible return Update Panel's AJAX Error in Global.asax's Application_AcquireRequestState? Because I write some codes FunA to check something at Global.asax's Application_AcquireRequestState, but when session timeout, user click the page (AJAX postback) it will cause FunA check false, then i want render some error message back. When HttpGET I can use Response.Write("<script...>alert('....');</script>") Response.End, But when HttpPost(AJAX) then "<script>..." will cause Client AJAX Error, It's possilbe return AJAX's Error in Application_AcquireRequestState Method?
  Thanks.
Ahtisam
Ahtisam United Kingdom on 8/12/2008 12:23 PM Hi Moses, I hope you are fine and doing well.

Well I am here again to ask you few things which I couldn't find it any where, so I think you can help me out with this.
What I am trying to do is I have 2 usercontrol one list the Name of Groups and when the user click on it then the second usercontrol will load all the user which are in that particular group.

Every thing is fine apart form this stupid Error in ajax call
=====
POST:
=====
{'Group':'1'}
=========
Response:
=========
{"Message":"Error executing child request for handler \u0027System.Web.UI.Page\u0027.","StackTrace":"
at System.Web.HttpServerUtility.ExecuteInternal(IHttpHandler handler, TextWriter writer, Boolean preserveForm
, Boolean setPreviousPage, VirtualPath path, VirtualPath filePath, String physPath, Exception error, String queryStringOverride)\r\n at System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter
writer, Boolean preserveForm, Boolean setPreviousPage)\r\n at System.Web.HttpServerUtility.Execute(IHttpHandler handler, TextWriter writer, Boolean preserveForm)\r\n at BaseDrift.renderpage.LoadSelectedFanList(String GalleryId) in D:\\BabeDrift_StagingServer\\BaseDrift\\renderpage.aspx.cs:line 30","ExceptionType":"System.Web.HttpException"}

I'll be waiting for your replay mate
Kind Regards
mosessaur
mosessaur Egypt on 8/12/2008 12:29 PM @ Ahtisam I am not able to get any information from the exception. But I have a question! does the loaded control (on demand one) render GridView or any control that require Form Tag? You can show me a snippet of the code of these controls
mosessaur
mosessaur Egypt on 8/12/2008 12:31 PM @ Rainmaker To be honest, I don't know! maybe I am not sure if I get what you mean or I am missing something. Sorry
Ahtisam
Ahtisam United Kingdom on 8/12/2008 12:53 PM First Control
=============
if($(detail).html() == "")
{
    //Prepare Progress Image
    var $offset = $(master).offset();
    $('#progress').css('visibility','visible');
    $('#progress').css('top',$offset.top);
    $('#progress').css('left',$offset.left+$(master).width());                    
    //Prepare Parameters
    var params = "{'GalleryId':'"+ OpenPlaylistId +"'}";                    
    //Issue AJAX Call
    $.ajax({
      type: "POST", //POST //GET
      //url: "WebService.asmx/LoadSelectedFanList", //Set call to Web Service Method
      url: "renderpage.aspx/LoadSelectedFanList", //Set call to Page Method
      data: params, // Set Method Params
      beforeSend: function(xhr) {
    xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");},
      contentType: "application/json; charset=utf-8", //Set Content-Type
      dataType: "json", // Set return Data Type
      success: function(msg, status) {
    $('#progress').css('visibility','hidden');
    $(detail).html(msg);
    $(detail).slideToggle("normal"); // Succes Callback
    },
      error: function(xhr,msg,e){
    $('#progress').css('visibility','hidden');
    alert(msg);//Error Callback
    }
      });


}
else
{
    //Toggle expand/collapse                  
    $(detail).slideToggle("normal");
}


<asp:UpdatePanel ID="pnlUpdate" runat="server">
<ContentTemplate>
<asp:GridView Width="100%" AllowPaging="false" ID="gvGrouplist" AutoGenerateColumns="False"
    runat="server" ShowHeader="False">
    <Columns>
  <asp:TemplateField>
      <ItemTemplate>
    <div onclick='LoadFans("#mainfanlist0","#fandetail","1")' id="mainfanlist0" style="display: inline; height: 22px;" class="group">
    EMail Gruop: 2 Users  
    </div>
      </ItemTemplate>
  </asp:TemplateField>
    </Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>

================




Second Control
==============

Control HTML
============
  <aspLaughingataList CssClass="playergallerydatalistCSS" ID="GroupUserDL" runat="Server"
  RepeatColumns="5" RepeatDirection="Horizontal" CellSpacing="0" CellPadding="0"
  ItemStyle-Width="100" OnItemCommand="FanResultDL_ItemCommand">
  <ItemTemplate>    
      <table>
    <tr>
        <td class="GalleryFrameMiddle">
      <!-- START IMAGE HTML -->
      <div style="height: 85px; top: 0pt; left: 0pt;">
          <aspTonganel runat="server" ID="DIV_ImageID" Visible="false">
        <div id="divplayertxtcode">
            <asp:Label ID="lblPlayerTxtCode" runat="server" Text='<%# Eval("TextCode") %>' Visible="false"></asp:Label>
            <asp:Label ID="lblUserID" runat="server" Text='<%# Eval("VoterId") %>' Visible="false"></asp:Label>
        </div>
          </aspTonganel>
          <aspTonganel runat="server" ID="DIV_UserBigImage" Visible="true">
        <div id="divplayerimage" style='background-image: url(<%# ConfigurationManager.AppSettings["BaseUrl"] + "/" + Eval("Picture") %>);
            background-position: center center'>
            <asp:ImageButton Width="98" Height="83" BorderWidth="1" ID="PlayerImage" runat="server"
          CssClass="PlayerImage" AlternateText='<%# Eval("Points") %>' ImageUrl='<%# ConfigurationManager.AppSettings["BaseUrl"] + "/images/GalleryScoreboard/FaceMask.png" %>' />
        </div>
          </aspTonganel>
      </div>
      <!-- END -->
        </td>
          <tr>
        <td class="GalleryEntrantName">
            <asp:Label ID="lblPlayerName" runat="server" Text='<%# Eval("UserName") %>' Visible="false"></asp:Label>
            <asp:LinkButton ID="lnkbtnloaduser" runat="server" CssClass="GalleryEntrantNameLink"
          Text='<%# Eval("UserName") %>'></asp:LinkButton>
        </td>
          </tr>
          <tr>
        <td class="GalleryEntrantVotes">
            <div class="GalleryEntrantVotesDiv">
          Votes&nbsp;&nbsp;&nbsp;&nbsp;<%# Eval("VoteCount") %></div>
        </td>
          </tr>            
        </td>
    </tr>
      </table>
  </ItemTemplate>
  </aspLaughingataList>
===========
Control .CS
===========
<script runat="server">
  protected override void OnLoad(EventArgs e)
  {
    if (this.GroupId != null)
        LoadGroupUser(int.Parse(this.GroupId));  
    base.OnLoad(e);
  }
  protected void LoadGroupUser(int FanGallId)
  {
    try
    {

        m_Connection.Open();
        Cmd = new MySqlCommand("sp_LoadGroupUsers", m_Connection);
        Cmd.CommandType = CommandType.StoredProcedure;
        Cmd.Parameters.Add("?GroupId_P", MySqlDbType.Int32);
        Cmd.Parameters["?GroupId_P"].Value = FanGallId;      
        myDataAdapter = new MySqlDataAdapter(Cmd);
        ds = new DataSet();
        myDataAdapter.SelectCommand = Cmd;
        myDataAdapter.Fill(ds);
        if ((ds != null))
        {
      if (ds.Tables.Count > 0)
      {
          GroupUserDL.DataSource = ds;
          GroupUserDL.DataBind();        
      }
        }


    }
    catch (Exception ex)
    {
        lblError.Text = ex.Message;
        lblError.Visible = true;
    }
    finally
    {
        m_Connection.Close();
    }


  }
</script>

==============



RenderPage.aspx.cs
==================

[WebMethod]
public static string LoadSelectedGruopUsers(string GroupId)
{
    Thread.Sleep(500);
    Page page = new Page();    
    FanResults ctl = (FanResults)page.LoadControl("~/controls/DisplayUsers.ascx");    
    ctl.GroupId = GroupId;
    page.Controls.Add(ctl);
    StringWriter writer = new StringWriter();
    HttpContext.Current.Server.Execute(page, writer, false);
    string output = writer.ToString();
    writer.Close();
    return output;
}

[WebMethod]
public DateTime GetCurrentDate()
{
    return DateTime.Now;
}

==================


Ahtisam
Ahtisam United Kingdom on 8/12/2008 12:55 PM This one is the correct ajax call

if($(detail).html() == "")
{
    //Prepare Progress Image
    var $offset = $(master).offset();
    $('#progress').css('visibility','visible');
    $('#progress').css('top',$offset.top);
    $('#progress').css('left',$offset.left+$(master).width());                    
    //Prepare Parameters
    var params = "{'GalleryId':'"+ OpenPlaylistId +"'}";                    
    //Issue AJAX Call
    $.ajax({
      type: "POST", //POST //GET
      //url: "WebService.asmx/LoadSelectedGruopUsers", //Set call to Web Service Method
      url: "renderpage.aspx/LoadSelectedGruopUsers", //Set call to Page Method
      data: params, // Set Method Params
      beforeSend: function(xhr) {
    xhr.setRequestHeader("Content-type", "application/json; charset=utf-8");},
      contentType: "application/json; charset=utf-8", //Set Content-Type
      dataType: "json", // Set return Data Type
      success: function(msg, status) {
    $('#progress').css('visibility','hidden');
    $(detail).html(msg);
    $(detail).slideToggle("normal"); // Succes Callback
    },
      error: function(xhr,msg,e){
    $('#progress').css('visibility','hidden');
    alert(msg);//Error Callback
    }
      });


}
else
{
    //Toggle expand/collapse                  
    $(detail).slideToggle("normal");
}
mosessaur
mosessaur Egypt on 8/12/2008 1:00 PM The issue is with your 2nd Control. you are using DataList. This will not work on this approach, You must use a control such as ListView or Repeater. Taking into account not to use any ASP.NET Control that will require postback such as buttons
Ahtisam
Ahtisam United Kingdom on 8/13/2008 10:43 AM Thanks Alot Moses
Problem Solved Laughing
Rainmaker
Rainmaker Taiwan on 8/14/2008 7:47 PM Sir, I mean when pageA click button to do postback through UpdatePanel's AJAX to Server. It will first run Global.asax's Application_AcquireRequestState Method, then go to pageA, right!
If I want at Application_AcquireRequestState Method write some code to throw exception, and pageA's Javascript can catch the exception. It's possible?
adriakuma
adriakuma Mexico on 9/1/2008 10:30 PM Hi Mosa I test you example, but i have to detail... I prove the control, and appears the dialog box with  "Error" (only print this *_*) , i try with to web service, and try with Safari and Google Chrome navigators and the mistake repeat, but i try with:

$(detail).html (" <table <tr <td> Print table </td </tr </table> ");

And work!!!

But with:
$(detail).html (msg);

Send the message (debug mode):

FileHtml: Incompatible Interface

Append: function () {
return this.domManip (arguments, true, false, function (elem) {
if (this.nodeType == 1)
---> this.appendChild (elem);
});
},
Line: 238 from the file jquery-1.2.3.min.js
I prove in remote computers access and repeat a "Error" dialog box *_*  .
I think meave its an error of my local configuration, you have any idea, please.
Cheers from Mexico
mosessaur
mosessaur Egypt on 9/2/2008 6:44 AM @adriakuma Not sure if this will work or not, but try this:
$(detail).html(msg.d);
adriakuma
adriakuma Mexico on 9/2/2008 7:42 PM Yeah!!

$(detail).html(msg.d);

WORKS!!!

You are a master chief.
Extended cheers from Mexico.
Good Job
murali krishna
murali krishna India on 9/4/2008 3:13 PM Hi Mosa ,
This example is very good and working well but I want to check and un-check ALL option .Could you send code for that if possible.

Thanks,
murali
mosessaur
mosessaur Egypt on 9/4/2008 3:24 PM @murali krishna Thank you Murali for your comment. Sorry but I didn't understand your request? you want to check and un-check all? what does that mean. Do you mean an option to expand all list or collapse them all?
murali
murali India on 9/5/2008 11:23 PM Hi Mosa ,
Ues I want to expand all list and collapse all  also.
could you provide if it is possible.
mosessaur
mosessaur Egypt on 9/6/2008 2:54 AM @murali I guess it is possible, but It might cause some performance issues. I'll try to look at it but actually I'll not be available soon as I am traveling and will have internet connectivity issue.
murali
murali India on 9/18/2008 7:38 AM Hi mosa,
I am waiting for your code, After you return from vacation  ,please send that code.
Gordon
Gordon United States on 9/30/2008 9:41 PM Thanks mosa, it is exciting sample , I download the sample and get it run ok.
But I cannot copy the same thing to my project , I get an error says:
Error: Sys.Net.WebServiceFailedException: The server method 'GetOrders' failed with the following error: System.Web.HttpException--Error executing child request for handler 'System.Web.UI.Page'

Can You help check my code:

sample.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="callback.aspx.cs" Inherits="northwindtest.callback" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "www.w3.org/.../xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>

    <script language="javascript" type="text/javascript">

        function Button1_onclick() {
            northwindtest.mytest.HelloWorld(onsayhello);
            PageMethods.GetOrders(ongetcontrol);

        }

        function ongetcontrol(result) {
            var div1 = $get("mysecondcontrol");
            div1.innerHTML = result;
        }

        function onsayhello(result) {
            $get("Text1").value = $get("Text1").value + result;
        }

    </script>
</head>
<body>
    <form id="form1" runat="server">
    <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true">
     <Services>
     <asp:ServiceReference Path="~/mytest.asmx" />
     </Services>
    </asp:ScriptManager>
    <div>
        <input id="Button1" type="button" value="button" onclick="return Button1_onclick()" /><input id="Text1" type="text" />
    </div>
    <div id="mysecondcontrol"></div>
    </form>
</body>
</html>


Sample.aspx.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace northwindtest
{
    public partial class callback : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        [System.Web.Services.WebMethod()]
        public static string GetOrders()
        {
            //System.Diagnostics.Trace.TraceWarning("In GetOrders");
            //System.Threading.Thread.Sleep(500);
            Page page = new Page();
            Control ctl = (Control)page.LoadControl("~/WebUserControl1.ascx");
            page.Controls.Add(ctl);
            System.IO.StringWriter writer = new System.IO.StringWriter();
            HttpContext.Current.Server.Execute(page, writer, false);
            string output = writer.ToString();
            writer.Close();
            return output;
        }
    }
}

webusercontrol1.ascx is a very simple control , I just drag 2 buttons and 2textbox without any code.
Gordon
Gordon United States on 9/30/2008 9:55 PM OOPS!,
I found the answer by read full of this post, thanks.
krishna
krishna India on 10/2/2008 12:13 PM Hi mosa,
Could you send code for Expand all items and collapse all items including with individual expand and collapse

Thanks,
krishna
sangita
sangita India on 10/2/2008 1:02 PM Thanks, Mosa. for such good articles,
I want confirmation is in your next post you have provided 'Building on demand Master/Detail grouping Grid with GridView and ASP.NET AJAX toolkit CollapsiblePanelExtender' so using AJAX and jQuery solution seems to be more performance oriented than  CollapsiblePanelExtender  right?
actually i need to implement same functionality with added requirement of collapse all/expand all. and more than that it will be n-layer instead of just 2 layers(master and detail). i will be thankful if you can provide some code/ suggestion for the same.
mosessaur
mosessaur Egypt on 10/2/2008 1:13 PM @krishna I'll do my best, I'm a bit busy with few things and preparing for another post. Sorry for not being fast enough.

@sangita jQuery is performing faster than ASP.NET AJAX. But ASP.NET AJAX controls ease the development. But this is not a big issue anyway. It will take me sometime to provide a another sample, busy till the end of this month. But I'll do my best.
sangita
sangita India on 10/3/2008 10:24 PM Hi Mosa,
i was developing 3 level( master-detail-detail) using this example but no luck as HttpContext.Current.Server.Execute(page, writer, false); method just executes and no O/P is sent on calling page i. I have added collapsible Div on usercontrol but it's not able to do anything(click/unclick and expand below grid). can you suggest some information regarding implementing 3 level grouping using any methodology?
sangita
sangita India on 10/3/2008 11:31 PM Hi mosa,
i got something for implementing this 3 level grouping. i did it by using another DIV from calling page.
thanks.
Lloyd George
Lloyd George India on 10/5/2008 3:46 AM Hi Moses,article was too good.And we all need more from you.For error with gridview in the user control i decorated the gridview with form tag/runat=server and its working fine for me.Also i referred to Scott Gu's wonderful blog where he gives a much cleaner approach for generating html

weblogs.asp.net/.../..._UpdatePanel-scenarios.aspx
Tacko
Tacko on 10/6/2008 4:19 PM Nice Post....

Im working on 1 to N GridView (not only 1 sublevel) Can someone help me??

thanks
Efe Kaptan
Efe Kaptan on 10/7/2008 3:06 AM Hi, thats superb job.

I want to ask a question. Is there a chance to store CustomerId value in control state instead of viewstate. I am asking bacause controls that use view state to store values will not work correctly if view state is disabled on any particular host page.

Thank you.
mosessaur
mosessaur Egypt on 10/7/2008 10:26 PM @Efe Kaptan I do not store CustomerId in ViewState!!!
If you noticed CustomerId is binded and is used as a parameter in the javascript function call showhide.
Efe Kaptan
Efe Kaptan on 10/10/2008 9:49 AM Moses, I am talking about below class:

public class CustomerOrders : UserControl
{

    public string CustomerId
    {
        get { return (string)ViewState["CustomerId"]; }
        set {ViewState["CustomerId"] = value;}
    }
}

this class is child class of CustomerOrders.ascx control and in GridViewDrillDownjQueryAjax.aspx.cs file you call above property like that:

ctl.CustomerId = customerId;
I wish i have explained my question clearly.
Thanks.
mosessaur
mosessaur Egypt on 10/10/2008 1:06 PM @Efe Kaptan well you can use control state, but you'll need to do some extra code to save and load it.
kamal
kamal Indonesia on 10/13/2008 5:30 PM hi moses, i have a problem when i use gridview 1 to N gridview, more than 1 sub level, can you give me advice about that??

thanks..
mosessaur
mosessaur Egypt on 10/13/2008 9:23 PM Sounds like many people is demanding multi level details!! I just need to think, perpare a demo and write about it.
skhan
skhan United States on 11/3/2008 8:35 AM Hey Mosa - Great write up! I've noticed that on the initial click, the div retrieves the data but doesn't open up. It shows the progress while loading the data and then it flashes really quickly and I have to click on the image again to open it up?
nwill
nwill Jamaica on 11/6/2008 7:01 PM Hey Moses- Great post however I am try to add another layer of drill down but I am not having much luck with it. First of all my page is display Transaction info. It should display all cashier, then we should be able to drill down and see each type of transactions they did (BUY or SELL), then they should be about to expand the transaction to view the details of each.
so it should be like this:
CASHIERS001:MARY JANE
|-->BUY (Count: 2 Total: $100)
   |--> Item1 1 @ $50 = 50
   |--> Item2 1 @ $50 = 50
|-->SELL (Count: 3 Total: $ 250)

I seems to get an error when if I put any Ajax controls on the user controls that displays the transaction summary, such as updatepanel, scriptmanager or callapsablepanelextender.

It there someting I am missing??
Thanks in advance



Txomin
Txomin United Kingdom on 11/19/2008 1:52 AM I get the same error as Cristiano in IE 7:
'htmlfile: No such interface supported' in this.appendChild(elem)

I tried in FF 3 I get the error
- Error: uncaught exception: [Exception... "Node cannot be inserted at the specified point in the hierarchy"  code: "3" nsresult: "0x80530003 (NS_ERROR_DOM_HIERARCHY_REQUEST_ERR)"  location: "http://localhost:57254/GridViewDrillDownJQueryAjax/scripts/jquery-1.2.3.min.js Line: 13"]

I'd appreciate your help
kris
kris United States on 12/1/2008 9:02 AM Hi,
Could you provide all items expand and collapse on gridview.
ONUR
ONUR Turkey on 12/2/2008 5:03 AM Hi Mosa,
I apply this demo my own project but I have some problem my problem is when I use ajax tab container detail will not firing do you have any idea please reply me thanks a lot happy coding....
ONUR
ONUR Turkey on 12/2/2008 5:06 AM Hi Mosa,
I use this demo in my own project so I have problem when I use ajax tabcontainer detail will not firing please give me feedback thanks happy coding...
mosessaur
mosessaur Egypt on 12/3/2008 1:48 AM @[ONUR] Sorry I don't have any idea why this happen! I need to test but currently I don't have enough time.
Hope you find a solution and please post it if you find it. Thanks
ONUR
ONUR Turkey on 12/3/2008 7:02 PM I find the problem your project is framework 2.0 I use visual studio 2008(3.5) when I change web config 2.0 to 3.5 its not firing and give
this error I can`t change my framework so I m keeping try to find solution
thanks happy coding...

Node cannot be inserted at the specified point in the hierarchy" code: "3
Sys$CultureInfo$_getAbbrMonthIndex("")ScriptRe...548069395 (line 7069)
ScriptResource.axd?d=DjHwLlomYHiuCg8w1iWl5edqXsII-SNUbUpKo-9IrTZ7dj7Mts2sLpB5gpx4dJkupPqS2iAfNCO9O8m_jHZfSg2&t=633260028140000000()()ScriptRe...140000000 (line 499)
[Break on this error] this._upperAbbrMonths = this...s.dateTimeFormat.AbbreviatedMonthNames);
Queston
Queston India on 12/6/2008 1:03 AM Gr8 work Mosa,
I am having a problem while using this technique in my project.
request.responseXML is returning null if am setting

Response.ContentType = "text/xml"

in my page Method
Queston
Queston India on 12/6/2008 1:25 AM got it

Response.ClearContent();
Response.ContentType = "text/xml";

had to written after..

HttpContext.Current.Server.Execute(page, writer, false);

and not before it

Can u enligtn me why Response Object is changed during the execution of Server.Execute() Method
brott
brott United States on 12/25/2008 5:06 AM Thanks a bunch.  Overall a nifty implementation and did exactly what I needed, though had to make a couple changes to get it to work properly with the OracleClient (the SelectParameters). Also converted to VB quite nicely. I also added some checkboxes to the detail grid - and the values can be posted to another page via a little javascript. I don't think it would be too difficult to modify that javascript to drop down another "sub-detail".

By the way, the images which are used to create the div "edges" generate a bit of overhead on each click. It's tough to emulate the effect without some type of image, but I found that simple background-color's helped in terms of speed and efficiency.

The odd thing with the PageMethod, was that I was unable to get it to work via the .NET generated template (Web User Control) which creates the code-behind automatically. I had to specifically remove the code-behind file, and generate a new class in App_Code - then link it back up with the html markup piece (via Inherits). Does that make sense?
Chris Klein
Chris Klein United States on 1/22/2009 5:44 PM Is there any way to get an EditItemTemplate to work on the detail?  I have the AJAX version which has the hover edit control but I just want the linkbuttons to show up. Now when I try it, it just closes the detail.
Faizan
Faizan on 2/8/2009 11:52 PM Hello its great I have used it.Can U please update it so that inside detail there is another detail gridview "inline Master/Detail record display" I need to display tasks which may con contain subtash and this subtask may contain a subtask and so on.ANy help or hint will be Great.
Rahul
Rahul India on 2/16/2009 4:28 PM This is not a good project.
Vijay
Vijay United States on 4/5/2009 4:24 AM Can you please provide an example with multiple columns (instead of 1) with sorting/paging on Parent GridView ?
Vijay
Vijay United States on 4/7/2009 6:23 PM Release 1.3.2 JQquery doesn't allow the expand/collapse.
mosessaur
mosessaur Egypt on 4/7/2009 11:44 PM @Vijay I didn't check that! I will check it and maybe update my sample
AvayaD
AvayaD United States on 4/14/2009 2:53 AM Hello Mosa,  

This is a great tutorial.  I have a question regarding a slightly different problem.  I am trying to build gridviews on the fly in codebehind and the gridviews have buttons in them that allows the user to edit the contents.  I would be building roughly 230+ seperate GridViews and panels needed to enable CollapsiblePanelExtenders.

The problem is that it takes awhile for the page to load all of the details and that is why I need to build this on the fly.  The ultimate goal is to have the site load with 230 panels containing the title of data listed in the collapsed panel below.  When the user clicks to expand the panel have the gridview inside load and refresh that updatePanel containing the gridview.

Am I way off or is there a better way to handle this?  Thank you for your help in advance.  I appreciate it.
Nick
Nick United States on 5/15/2009 11:16 PM Is there any gridview drilldown code or sample with update and delete functionality besides the one with the nested updatepanel that is unusable because of it's performance problem? Thanks in advance!
Deepak
Deepak United States on 5/19/2009 7:47 PM Hi Mose,

Nice article, Could we use LinqDataSource instead of SQLDataSource in above example. If yes then please let me know how??

thanks in advance.

trackback
.Net Discoveries on 7/1/2009 6:19 AM Using the AJAX Control Toolkit’s CollapsiblePanel in a GridView

Prologue On our company website, the one I mention so frequently (or is it infrequently as often as I
bouket
bouket France on 7/4/2009 3:18 PM Hello,

I try to run this project under visual studio 2008/ framework 3.5 but he

doesn't work (detail view doesn't work, error : No such interface

supported)

Why?

Thanks.
Rody van Sambeek
Rody van Sambeek Netherlands on 7/21/2009 11:56 PM Thanks for showing me how to call Web methods using jQuery, however I have the following situation:

- Default.aspx reads a set of web user controls (.ascx's)
- One Web User Control contains a controls with a jQuery event attached
- jQuery event calls the webmethod on the default.aspx
- Webmethod saves some data to the database

However, I would like to seperate the webmethod from default.aspx for code encapsulation. But the web user control does not support web methods, or at least, I can't get it to work.

So I use an external web service (asmx) to do this. This works, however I would like to encapsulate the webmethod in the user control. Is this actually possible?

Rody van Sambeek
Legend
Legend People's Republic of China on 8/3/2009 11:24 PM God job,But i have a question! I make a demo by myself but it looks some mistakes,Jqery can't receive the value from aspx and i use asmx,it is also the same mistakes.
saleh
saleh Saudi Arabia on 8/30/2009 2:55 PM Hi Moses, thanks for the great example! It's just what I was looking for. i have seen the demo and code I really like the way you are doing all this
and I want to impalement some like this in my project, but using vb.net and asp 2.
thanks again,,,,,,,
trackback
灵动生活 on 9/6/2009 4:29 AM 使用Ajax和Jquery实现GridView的展开、合并

使用Ajax和Jquery实现GridView的展开、合并
电子商务网站中,查询会员的订单,点击“會員”,展现此会员的订单列表。
Comments are closed