Recently I was working on a utility to export SharePoint list view data to a CSV file.. The logic was to open an application page using SharePoint's dialog framework, do the export logic in page-load of that application page and finally close the pop-up..
I thought closing the pop-up after completion would be fairly simple. I thought I can just use
Response.Write("<script type='text/javascript'>window.frameElement.commitPopup();</script>");
after process completion. But here was the challenge..To save the CSV data, I had to use the following code:
HttpContext context = HttpContext.Current;
context.Response.Clear();
context.Response.Write(csvData.ToString());
context.Response.ContentType = "text/csv";
context.Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName + ".csv");
context.Response.Flush();
context.Response.End();
The problem was, after changing the content type of Response to "text/csv", it was not possible to execute any JavaScript from server code to close the pop-up window..
After trying many options, I was about to give up when I found this method definition on MSDN..
SP.UI.ModalDialog.commonModalDialogClose(dialogResult, returnVal);
Closes the most recently opened modal dialog with the specified dialog result and return value.
Now, the solution was simple.. All I had to do was to set a cookie in the server side after process completion, and in the parent page, run a timer job every few seconds in JavaScript to check for the same cookie, and if found, delete the cookie, stop the timer and close the pop-up..
Note: To process the cookie in JavaScript I used this great library, because of which it turned out to be just a single line of code..
http://code.google.com/p/cookies/
Here is the complete code..
Javascript to open and close the pop-up:
function OpenPopUp() {
var oUrl = 'http://mysite/_layouts/SPExcelExport/SPExcelExport.aspx;
var options = {
title: 'Excel Export',
allowMaximize: false,
showClose: true,
width: 300,
height: 90
};
SP.UI.ModalDialog.commonModalDialogOpen(oUrl, options, null, null);
//Open pop-up
var millisecondsToWait = 2000;
//Run every 2 seconds to check for cookie
var intrvl = setInterval(function () {
if (jaaulde.utils.cookies.get('csvexportcookie') != null) {
//check if cookie is found
jaaulde.utils.cookies.del('csvexportcookie');
//Delete the cookie
SP.UI.ModalDialog.commonModalDialogClose(1, 1);
//Close the pop-up
clearInterval(intrvl);
//Clear timer
}
}, millisecondsToWait);
};
Server side code in the pop-up page:
HttpCookie oCookie = new HttpCookie("csvexportcookie", "completed");
//Set the Cookie
Response.Cookies.Add(oCookie);
HttpContext context = HttpContext.Current;
//Write the CSV data to current response
context.Response.Clear();
context.Response.Write(csvData.ToString());
context.Response.ContentType = "text/csv";
context.Response.AppendHeader("Content-Disposition", "attachment; filename=" + fileName + ".csv");
context.Response.Flush();
context.Response.End();
That was it.. Problem solved!