Creating a Lookup Modal Popup
UPDATE: 8/14/2007 : This post has been revamped and cleaned up. Click here for the new post.
For one of my current applications, I have the need to create a series of modal popups for data selection, information, and such. These will be more potent than the standard modal popup extender because they must post back onto themselves.
The modal popup extender contains a panel that looks like:
<asp:Panel ID=”pnlLookupStudentPanel” runat=”server” Height=”400px” Width=”500px”
Style=”display: none; background-color: White ; border: solid 2px blue; padding: 20px;“>
<asp:UpdatePanel ID=”upLookupStudent” runat=”server”>
<uc1:LookupStudentControl ID=”LookupStudentControl” runat=”server” />
</asp:UpdatePanel> <asp:Button ID=”btnStudentFound” runat=”server” Text=”Attach Students” OnClick=”btnStudentFound_Click” />
<asp:Button ID=”btnStudentCancel” runat=”server” Text=”Cancel” />
The actual form is contained in a custom user control, and simply contains the UI elements you see above, a gridview, and an object data source that queries our “GetStudentCollectionByFirstorLastName” method via a standardized framework library.
You’ll notice that the user control (or the form that we’ll be posting back) is contained in an UpdatePanel. This is a MUST or when you click Search (or anything that calls a postback), your entire modal popup will close. For this example, that’s bad.
The modal popup extender, part of the AJAX Toolkit, is quite simple:
<ajaxToolkit:ModalPopupExtender ID=”LookupStudentPopup” runat=”server” CancelControlID=”btnStudentCancel” DropShadow=”true” PopupControlID=”pnlLookupStudentPanel” TargetControlID=”btnLookupStudent” />
You notice that the OkControlId and OnOkScript are not specified; this is to ensure that the Search and Attach Students buttons you see above are not hidden. More information about this here. One thing to point out: Attach Students and Cancel CANNOT be part of your User Control (and even using a User Control is unnecessary—I just did it for a bit of code cleanup).
So, we’ll search for a student named Tyler at a specific school (note: black blocks… yeah, imagine there’s data back there…). We’re now ready to “Select” the row we wish to relay back to our application.
To accomodate this, our user control must have a property; we’ll call it Selected Students.
private List<int> _selectedStudents;
public List<int> SelectedStudents
if (_selectedStudents == null)
if (Session[“LSC_SelectedStudents”] == null)
_selectedStudents = new List<int>();
_selectedStudents = (List<int>)Session[“LSC_SelectedStudents”];
_selectedStudents = value;
Session[“LSC_SelectedStudents”] = _selectedStudents;
Now, this is where my gray area begins… to be honest, I couldn’t keep it from flushing the property between selections (read: selecting multiple students) without pushing it into Session. I’d love to hear if there’s a better way.
What we’ll want to do, since that Select button noted in our GridView, is to capture the SelectedIndexChanged event. In this example, I’m taking the second column of the GridView (SelectedRow.Cells.Text) and placing it into an generic collection of integers (a List<int>) that I’ll return to the application.
protected void gvStudentList_SelectedIndexChanged(object sender, EventArgs e)
int selectedStudentId = ConversionTools.ConvertInteger(gvStudentList.SelectedRow.Cells.Text);
List<int> temp = SelectedStudents;
// First, determine if we’re selecting or unselecting, based on color.
if (gvStudentList.SelectedRow.BackColor == System.Drawing.Color.LightGreen)
// Row already selected, let’s unselect it.
gvStudentList.SelectedRow.BackColor = System.Drawing.Color.Empty;
// Remove StudentId from collection.
// Set row to LightGreen to indicate selection.
gvStudentList.SelectedRow.BackColor = System.Drawing.Color.LightGreen;
// Add StudentId to collection.
SelectedStudents = temp;
Again, a gray area of accessing the setter of the property without creating a junk “temp” first. I’ll keep researching on how to clean it up, but.. *cough* it works.
We now need to associate an “On Click” for our Attach Students. This captures the information stored in the public property SelectedStudents of our user control and then iterate through to pull out the names of the students.
protected void btnStudentFound_Click(object sender, EventArgs e)
lblStudentInfo.Text = “”;
foreach (int studentId in LookupStudentControl.SelectedStudents)
StudentRecord student = Students.GetStudentRecordByStudentId(studentId, false);
lblStudentInfo.Text += student.FullName + ” “;
If I just needed the names, I could add those to our Generic List rather than identification numbers, however, other parts of the page require their Id. Or, to build on this, I could simply return a StudentCollection (a Collection of StudentRecord objects, which the GridView from the popup was originally built on), but that’s for another day.