Home > .net 2.0, AJAX, c#, Visual Studio 2005 > Creating a Lookup Modal Popup

Creating a Lookup Modal Popup

June 4, 2007

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:

Modal popup extender's contents

<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”>
<ContentTemplate>
<h2>Lookup Student</h2>
<uc1:LookupStudentControl ID=”LookupStudentControl” runat=”server” />
</ContentTemplate>
</asp:UpdatePanel> <asp:Button ID=”btnStudentFound” runat=”server” Text=”Attach Students” OnClick=”btnStudentFound_Click” />
<asp:Button ID=”btnStudentCancel” runat=”server” Text=”Cancel” />
</asp:Panel>

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.

Modal popup extender's contents with filled gridview

To accomodate this, our user control must have a property; we’ll call it Selected Students.

    private List<int> _selectedStudents;

    public List<int> SelectedStudents

    {

        get

        {

            if (_selectedStudents == null)

            {

                if (Session[“LSC_SelectedStudents”] == null)

                {

                    _selectedStudents = new List<int>();

                }

                else

                {

                    _selectedStudents = (List<int>)Session[“LSC_SelectedStudents”];

                }

            }

            return _selectedStudents;

        }

        set

        {

            _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[1].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[1].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.

            if (temp.Contains(selectedStudentId))

            {

                temp.Remove(selectedStudentId);

            }

        }

        else

        {

            // Set row to LightGreen to indicate selection.

            gvStudentList.SelectedRow.BackColor = System.Drawing.Color.LightGreen;

           

            // Add StudentId to collection.

            if (!temp.Contains(selectedStudentId))

            {

                temp.Add(selectedStudentId);

            }

        }

        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.

Tags: , ,

  1. June 13, 2007 at 3:14 am

    I am curretly working on a similar solution, this time for Patient lookup for a medical website. Very well written and easy to follow blog entry (I had the issue with the controls in the panel not being in an UpdatePanel).

    I do have one question though, how do you handle clients with no Javascript support? Or is Javascript a requirement for your application? I was thinking of having some way to generate a standard search area within the main form if it was disabled, but I haven’t found a way to detect that absance of Javascript.

  2. June 13, 2007 at 5:43 am

    Hmm. Detecting javascript would be an interesting issue.

    Since AJAX == JavaScript, my apps require it from the client side. I do, however, have the luxury of assumption since 99% of what I do is internal/intranet-based solutions. Our public internet site is the exception since it must be cross-browser and 508 compliant.

    One possible way would be to detect JavaScript on Page_Load. I didn’t detail it above, but my popup “windows” are actually in separate Web Controls… such as LookupStudentPopup.ascx, etc. Rather than directly loading those on the page, you could use a decision point or something similar to:

    if (Request.Browser.JavaScript)
    {
    LoadMPEPopup(patientBox);
    }
    else
    {
    LoadStandardSearch(patientBox);
    }

    As far as a replacement, I honestly don’t know what all you can do without JavaScript support; that’d be an interesting topic to investigate.

  1. August 14, 2007 at 3:15 pm
Comments are closed.
%d bloggers like this: