Using AJAX ModalPopup with GridView control

This actually applies to other data controls such as Repeater and DataList, but here I will just focus on GridView control.

On ASP.NET web site, there is a tutorial titled “using ModalPopup with a Repeater Control”. To make the ModalPopup work, the tutorial says that the ModalPopupExtender must be put within the <ItemTemplate> section of the Repeater control, but the popup panel is outside the Repeater control. The reason is that if the ModalPopupExtender control is outside the Repeater control, then the LinkButton control in the <ItemTemplate> section of the repeater is not accessible to the ModalPopupExtender and you can’t assign the LinkButton’s ID to ModalPopupExtender’s TargetControlID, that is why you must put both controls in the <ItemTemplate> section of the repeater. This approach works well, but I don’t prefer to use it. The reasons are:

1. It is used to display static content in the ModalPopup. What if I want to change the content in the ModalPopup based on the row selected. For instance, there is a View Details button on each row which upon clicked will display more information in the ModalPopup? Of course, you can add a popup Panel control also in the <ItemTemplate> section of the repeater whose content can be loaded when the row is created or bound, but it will lead to the second disadvantage of the approach:

2. It has to inject some extra HTML code for each row.

Let me show you an example to show what I mean.

Take the following screen shot at an example:

2009-04-08_164920

If we use the approach introduced in the tutorial, then after the page is loaded, the page source of the GridView’s each row will look like this:

<tr class=”grid-item”> <td>1</td><td>FirstName_1</td><td>LastName_1</td><td>123-456-7890</td> <td>FirstName_1.LastName_1@TechProsZone.net</td><td>Some random notes here.</td> <td> <a id=”ctl00_Content_gvCustomerList_ctl02_lbtnView” href=”javascript:__doPostBack(‘ctl00$Content$gvCustomerList$ctl02$lbtnView’,”)”>View Details</a> </td> </tr>

Also at the end of the page, you will see something like this:

Sys.Application.add_init(function() { $create(AjaxControlToolkit.ModalPopupBehavior, {“PopupControlID”:”ctl00_Content_gvCustomerList_ctl02_pnlEditCustomer”,……); });

 

The above AJAX function call will be injected for each LinkButton control in the GridView. So if you have ten View Details control in the GridView, then the above function call with different control ID will be injected ten times. What is more, if you want to display dynamic information in the ModalPopup as I mentioned before, then you will need to add the popup panel in the same <ItemTemplate> of the repeater and populate them when a row is created. This approach will inject even more HTML code when the page is rendered to browser, plus the ViewState will get larger as well because of the addition of the popup panel. Just think about how bloated the page will be when you have more than 100 rows to display!

A Better Approach

An approach I prefer to use is to move the ModalPopupExtender control and the popup Panel control outside the GridView. In another word, there is only one ModalPopupExtender control and one popup Panel, and the content of the Panel will be populated on the fly when a row is selected or a button in a row is clicked, then ModalPopupExtender.Show() is called to display the popup.

2009-04-09_095327

This approach will only inject one Sys.Application.add.init() function call in the rendered HTML and greatly reduce the ViewState size because there is only one popup Panel control, in addition, it is very flexible to control the content of the popup. However, you may ask: how can I assign the Edit button’s ID to ModalPopupExtender’s TargetControlID property if the ModalPopupExtender is outside GridView? The answer is “No, you cannot”, but the good news is you don’t have to assign the Edit button’s ID to the TargetControlID property; you can assign any server control to this property! But if I assign a control to TargetControlID and when I click on the control, will it trigger the ModalPopup? Yes, it will, that is why we need to hide the control so no one will be able to click on it! Keep it in mind though, you cannot set the cotnrol’s Visible=False to hide the control, and you will have to use CSS style to hide the control as follows:

<asp:Label ID=”lblPopupTargetID” runat=”server” Style=”display: none;”></asp:Label>

Once this is done, all the rest is very simple. Here is the sample ModalPopupExtender:

<cc1:ModalPopupExtender ID=”mpeEditEmployee” runat=”server” TargetControlID=”lblPopupTargetID” PopupControlID=”pnlEditCustomer”> </cc1:ModalPopupExtender>

 

Then in GridView’s RowCommand event handler, just populate the content of the ModalPopup, then call:

Me.mpeEditEmployee.Show()

Viola, the ModalPopup pops up. When you are done whatever job you need to do, just call:

Me.mpeEditEmployee.Hide()

It will close the ModalPopup window.

Hope this helps.

4
Leave a Reply

avatar
4 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
4 Comment authors
mohanMingLarsBrian Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Brian
Guest

Thanks for this write up. It helped me do what I was wanting to do.

Lars
Guest
Lars

A great way of solving a classic problem. Thanks alot.

Ming
Guest
Ming

I appreciate the write up, but if you have a cascading dropdown list in the modal popup it doesn’t want to work. Indicating that multiple instances of the CascadingDropDown with the same name are being created.

mohan
Guest
mohan

I m not clearly understood. (practically)