Updated: Creating a Lookup Modal Popup

The ModalPopupExtender continues to be the most diverse and absolutely fantastic part of the AJAX Control Toolkit to date. While the other controls do “cool things,” the MPE really helps add a level of usability to applications and bridge the gaps for those users who are still a bit less grounded in web-based applications and long for the familiarity of their client/server applications.

Okay, 4 projects and several scenarios later, I’ve reworked a bit of the code I originally posted up back in June.

Some things I’ve discovered:

A user control isn’t totally necessary and a custom control is painful to implement due to the lack of a designer. The more I think about it, the more a true drag/drop control would be cool… but I just can’t see it for now. You CAN encapsulate each of these popups into user controls, but I didn’t see any real advantage to it unless you have HUGE ASPX pages and have trouble keeping the code together.

Session (my choice, better or worse) or ViewState is your friend due to the constant “refreshing” of the page. If there’s a better way than using Session or ViewState, I’m still interested!

Paging is possible within the popup!

We’ll use the same example as the last post: looking up a student.

Thecode is quite simple: two TextBox controls, two Button controls, and a DropDownList. The DropDownList has the AJAX Control Toolkit’s ListSearchExtender control applied to it. I LOVE this control (being a keyboard guy). There’s also a GridView that is hidden until results are found (by clicking Search).

To build the popup, our code looks pretty slim. The ModalPopupExtender, a Panel, the UpdatePanels, and controls mentioned above.

Our ModalPopupExtender (MPE) code specifies the PopupControlId (our Panel), the button that will activate it, and the Css to format it like I have above.

<AjaxToolkit:ModalPopupExtender

ID=”StudentLookupPopupExtender”

runat=”server”

PopupControlID=”StudentLookupPanel”

TargetControlID=”AddStudentsButton”

BackgroundCssClass=”ModalBackground”/>

Our Panel control specifies it’s own CSS class.

<asp:Panel

ID=”StudentLookupPanel”

runat=”server”

CssClass=”PopupPanel”>

Finally, our UpdatePanel sets the mode to Conditional to prevent other controls (just incase) from getting in the way.

<asp:UpdatePanel

ID=”StudentLookupUpdatePanel”

runat=”server”

UpdateMode=”Conditional”>

Our GridView has two events associated with it: PageIndexChanging and RowCommand. PageIndexChanging will allow us to page through our results set and Rowcommand will be associated with our Select command we’ll use later. Beyond that, for this example, everything is VERY standard. Bound fields. Very exciting, right?

<asp:GridView

ID=”StudentLookupGridView”

runat=”server”

AutoGenerateColumns=”False”

Style=”text-align: center”

AllowPaging=”True”

OnPageIndexChanging=”StudentLookupGridView_PageIndexChanging”

Width=”100%”

OnRowCommand=”StudentLookupGridView_RowCommand”>

<Columns>

<asp:ButtonFieldCommandName=”SelectStudent”Text=”Select”/>

<asp:BoundFieldDataField=”StudentId”HeaderText=”Student Id”/>

<asp:BoundFieldDataField=”FullName”HeaderText=”Student Name”/>

<asp:BoundFieldDataField=”SchoolName”HeaderText=”School”/>

<asp:BoundFieldDataField=”Grade”HeaderText=”Grade”/>

</Columns>

</asp:GridView>

So, we have a total of four events to code against. I’ll explain in the order that they would normally flow.

The Search button’s Click

The GridView’s PageIndexChanging

The GridView’s RowCommand

The Close button’s Click

Search Button

The Search button will do most of the heavy lifting for the entire pop-up. It will take the entry information, go out, query the data source, and populate our GridView. For my example, my data source is a method in our framework library. Any SQL, Oracle, Object, or even LINQ data source would suffice.

Prior code has populated the Session with an incident (a record) object. In the event this is a repeat search, set the back color of our GridViewRows to light green (selected color). That part is not necessary, simply a visual cue for my customers. You might be asking: why did you add your results set to Session? For our data paging, of course! Why requery?

Very simplistic and textbook; though several examples show requerying the datasource… in our environment, that data source is only populated once a day. If requerying is necessary, this is the event you’d do it in.

GridView’s RowCommand

Now we’ve found the record we’re interested in and are ready to select it. When you click ‘Select’, the SelectStudent command fires and is caught by the GridView’s OnRowCommand event.

Okay… in this event, we’re simply capturing the second cell (the student’s ID) and placing it into a variable, comparing it to our object in Session, and then taking action. The pseudo code would look similar to:

If record in memory’s student Id == the row student Id selected, then remove the color from the row and set the record’s student id to nothing because we’re “deselecting” that student”.

If the record in memory’s student Id != the row student Id selected, then color it light green and set our record’s student Id to the selectedStudent variable (which happens to be the second cell’s text value). We’re “selecting” this row.

So, now that we’ve updated the record in session to the “selected” student, we’re ready to close our popup.

Close Button

This code will vary for EVERYONE depending on what they’re using the popup for. You could be populating a form on your parent web page, you could be modifying a database, you could be sending an online order to Pizza Hut for pizza (I’m hungry, send food, Pizzahut.com is blocked here. )

For me, I populate a placeholder back on the primary web form with a HyperLink control (that opens a popup that allows the user to view details about the student, but that’s beyond the scope of this).

I could encorporate that into the RowCommand, but I didn’t want to constantly be updating the control incase the user got click happy and was selecting… unselecting… selecting.. unselecting.. etc.

Styles

A quick note is to the styles I used. I like the alpha opacity blending to give that “dimmed” effect—looks very sweet and helps reiterate to users that they should pay attention to the bright window in front of them. I also have the display: none commented out still. See the post here for details.

.PopupPanel

{

width: 500px;

border: solid2px#5D7B9D;

background-color: #F5F5DC;

padding: 10px10px10px10px;

/* display: none; This won’t work due to a “bug” with the ModalPopup AJAX Control */

True, and there are definately still occassions I push and pull my own information… but, the efficiency battle is a long and hard one–especially in my field, public education, where the “end product” has absolutely nothing to do with technology (our product is educating kids, the systems I create simply support that).

If someone, even if I was using Google, Adobe, or another company’s AJAX framework, it’s still creating the building blocks and letting THEM worry about the details. My responsibility is understanding how it works and why… Thankfully, they’ve provided a lot of documentation and even, for like the AJAX Control Toolkit, the entire source code to peruse.

It’s not “bad” to want to roll your own, but you gotta weigh efficiency vs. functionality.🙂 No new wheel creations here…🙂

Antony

September 14, 2007 at 11:10 am

Hi there, you mention in your entry that “Paging is possible within the popup!”. I’ve tried for hours and I must be missing something.

UpdatePanel is inside Popup Panel but I am using master pages and have an updatepanel across the content.

Can you please post/email source so that I can check what I’m doing wrong.

I’ll double check when I get back home tonight and post up if there’s any difference.

Dinh Dinh

October 10, 2007 at 6:48 pm

After reading your post I would like to do the same but I could not get the StudentLookupSearchButton_Click to fire. The moment I click on Search the popup display with an empty grid. The post back did not occur to fill the grid with the search info. Am i missing somthing?

Do you have your grid inside an UpdatePanel? Post up your code (or email me at tiredstudent@gmail.com) and let’s take a look.🙂

Dinh Dinh

October 11, 2007 at 11:03 am

Thank you for your reply. I found a way to make it work. I assigned mpe TargetControlID to a hidden button control. Therefore, when the user click the search button it will fired search_onclick event and fill in the grid.

Without your sharing knowledge, I would never able to do this.

Many many thanks,
dinh.

Joel WZ

April 4, 2008 at 10:22 am

I am looking at the code here and am having a little trouble piecing it all together. Do you have the code where you can up load it, so it will be a little more clear? I am specifically looking at the placement and contents of the various panels, update panels, etc.

Okay, here ya go. The same concepts apply and this code should stand on it’s own–it’s pretty heavily code commented. It uses the Northwind database to pull up a MPE, select a product, then pass that product via Session back down to the calling page.

I have a masterpage and four content pages and in one of the content pages theres a gridview and a modalpopupextender. i need to popup an image on click of on of the columns in the grid. I am trying to do it, but when the popup shows up, the page behaves very weird.
the page becomes like very large and we can keeep on scrolling!!!

No, unfortunately, I don’t. The project could easily be translated to VS2005 and .NET 2.0 by simply referencing the the v1.0 version of ASP.NET AJAX and replacing the LINQ I used for the data binding with simple DataTables/DataReaders.

The overall functionality of the GridView, ModalPopupExtender, and such remains the same.