I recently wrote a WebPart that allows you to show SharePoint List-Items transformed by an XSL-Stylesheet. I needed the user to be able to choose the SharePoint list and the view that will serve as the data source for the transformation. I wanted to make this as confortable as possible and I wanted to have something like in the Content-Query WebPart where I can pick a list using a dialog popup that shows the structure of the current site collection.
Doing some research with .NET Reflector (a tool that must come from heaven!), i found out that it is not that hard to achieve. You simply have to copy and adjust some client-side JavaScripts and there you go. I will skip the details and just past the necessary code, I believe it is pretty self-explaining:
/// <summary>
/// Creates all JavaScript functions and loads actual List-DropDown values.
/// </summary>
/// <param name="e"></param>
protected override void OnPreRender(EventArgs e)
{
#region Configure ListPicker
ScriptLink.Register(this.Page, "PickerTreeDialog.js", true);
string lastSelectedListId = string.Empty;
if (!this.WebId.Equals(Guid.Empty) && !this.ListId.Equals(Guid.Empty))
{
lastSelectedListId = SPHttpUtility.EcmaScriptStringLiteralEncode(
string.Format("SPList:{0}?SPWeb:{1}:", this.ListId.ToString(), this.WebId.ToString()));
}
string script = "
var lastSelectedListSmtPickerId = '" + lastSelectedListId
+ "';
function mso_launchListSmtPicker()
{
if (!document.getElementById) return;
var listTextBox = document.getElementById('"
+ SPHttpUtility.EcmaScriptStringLiteralEncode(_txtListUrl.ClientID) + "');
if (listTextBox == null) return;
var serverUrl = '"
+ SPHttpUtility.EcmaScriptStringLiteralEncode(SPContext.Current.Web.ServerRelativeUrl) + "';
var callback = function(results)
{
if (results == null
|| results[1] == null
|| results[2] == null) return;
lastSelectedListSmtPickerId = results[0];
var listUrl = '';
if (listUrl.substring(listUrl.length-1) != '/') listUrl = listUrl + '/';
if (results[1].charAt(0) == '/') results[1] = results[1].substring(1);
listUrl = listUrl + results[1];
if (listUrl.substring(listUrl.length-1) != '/') listUrl = listUrl + '/';
if (results[2].charAt(0) == '/') results[2] = results[2].substring(1);
listUrl = listUrl + results[2];
listTextBox.value = listUrl;
"
+ "__doPostBack('" + this.ClientID + "','');}
LaunchPickerTreeDialog('CbqPickerSelectListTitle','CbqPickerSelectListText','websLists','', serverUrl, lastSelectedListSmtPickerId,'','','/_layouts/images/smt_icon.gif','', callback);
}";
this.Page.ClientScript.RegisterClientScriptBlock(typeof(SPListToolPart), "mso_launchListSmtPicker", script, true);
#endregion
#region Configure ViewPicker DropDownList
if ((!string.IsNullOrEmpty(_txtListUrl.Text) && _ddlViews.Items.Count == 0)
|| _listSelectionChanged)
{
_ddlViews.Items.Clear();
if (!string.IsNullOrEmpty(_txtListUrl.Text))
{
using (SPWeb web = SPContext.Current.Site.OpenWeb(this.WebId))
{
foreach (SPView view in web.Lists[this.ListId].Views)
{
_ddlViews.Items.Add(new ListItem(view.Title, view.ID.ToString()));
}
}
_ddlViews.Enabled = _ddlViews.Items.Count > 0;
}
else
{
_ddlViews.Enabled = false;
}
}
#endregion
base.OnPreRender(e);
}
Download the full source code from here.
