This week I got to play with some of the controls in the AJAX Control Toolkit, specifically the Modal Popup Extender. I hadn’t gotten a chance to sink my teeth into anything AJAX so I was pretty excited to see what it offers. On my current project I’m building custom web parts for a SharePoint application being used on limited size screens (think 800x600). As such we need to be very resourceful with screen real estate and limit the number of page changes.
The Modal Popup Extender sounded like a great fit for popping up additional entry forms without causing the user to navigate away from the primary entry screen. As many people who have attempted to implement the Modal Popup Extender on SharePoint can attest (example 1 & example 2) there are compatibility issues with properly viewing the popup. I quickly ran into some of those issues with the pop up not appearing at the X and Y coordinates specified, the background CSS wasn’t properly rendered, or a host of other errors. I added the below DOCTYPE tag to the master page as suggested by many people.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Adding the DOCTYPE did help rendering the modal popup, but I began to see errors rendering out of the box SharePoint controls. As I wasn’t willing to sacrifice out of the box controls for the modal popup extender, we began to search for alternatives.
I quickly found an example offered on a forum, but the formatting and implementation were not very clean or well suited to my needs. I decided to clean up the code and below is what resulted. Now we have a modal popup box with disabled background functioning through a web part.
Add the first control which will be the darkened background panel.
private Panel ModalBackgroundPanelControl()
{
// panel will hold modal popup items
Panel pnlModal = new Panel();
pnlModal.ID = "pnlModal";
pnlModal.Style["display"] = "none";
pnlModal.Style["position"] = "absolute";
pnlModal.Style["left"] = "0px";
pnlModal.Style["top"] = "0px";
pnlModal.Style["z-index"] = "9";
pnlModal.Style["background-color"] = "#383838";
pnlModal.Style["filter"] = "alpha(opacity=60)";
return pnlModal;
}
Add the second control which will be the modal popup panel. This panel contains an update panel which will house some controls of its own (buttons, textboxes, inputs, etc). I place all but the OK button inside this update panel since we want only the OK button to perform a postback (which resets the modal popup) and the other input controls to maintain the modal popup.
private Panel ModalSelectStoresPanelControl()
{
Panel pnlSelectStores = new Panel();
pnlSelectStores.ID = "pnlSelectStores";
pnlSelectStores.Style["display"] = "none";
pnlSelectStores.Style["position"] = "absolute";
pnlSelectStores.Style["left"] = "250px";
pnlSelectStores.Style["top"] = "25px";
pnlSelectStores.Style["z-index"] = "10";
pnlSelectStores.Style["background-color"] = "#FFFFFF";
// add update panel so that interior controls added don't perform postback
// update panel contains its own controls for program logic
pnlSelectStores.Controls.Add(ModalSelectStoresUpdatePanelControl());
// add OK button control
pnlSelectStores.Controls.Add(AcceptChangesButtonControl());
return pnlSelectStores;
}
Lastly is a “Select Stores” button which will fire off the modal popup. Note the Javascript event handler which essentially sets the display attribute to none or showing (block).
private Button SelectStoresButtonControl()
{
Button btnSelectStores = new Button();
btnSelectStores.ID = "btnSelectStores";
btnSelectStores.Text = "Select Stores";
// get reference to the client id for popup panels
string modalPanelClientId = ((Panel)this.FindControl("pnlModal")).ClientID;
string selectStoresPanelClientId = ((Panel)this.FindControl("pnlSelectStores")).ClientID;
btnSelectStores.Click += new EventHandler(SelectStoresButtonClicked);
// set onclick event so that popups display and resize to fit screen
btnSelectStores.Attributes.Add("onClick", "javascript:document.getElementById('" + modalPanelClientId + "').style.width = document.body.clientWidth + 'px';document.getElementById('" + modalPanelClientId + "').style.height = document.body.clientHeight + 'px';document.getElementById('" + modalPanelClientId + "').style.display='block';document.getElementById('" + selectStoresPanelClientId + "').style.display='block';");
return btnSelectStores;
}
Screenshots of the popup in action. You can see that the popup contains a number of additional controls not shown above in my code.
There is one drawback that I haven’t yet overcome. Currently my code resizes the background panel to be the size of the internet browser window. If the user resizes the window or if the popup content extends beyond that size then the user can edit items in the newly extended area. I will look into disabling resizing and scroll bars, but that doesn’t fully remove the problems. If you have suggestions for overcoming those issues please feel free to share.
Wednesday, May 27, 2009 8:46 PM