Ever since I saw the Content Query web part provided by the SharePoint Publishing Infrastructure, I was always keen to see the editor part of this web part. When you edit and modify this web part you will find that there is a browse button which allows us to open a pop up window where we can navigate through sites and lists in the site collection and select any one of it. And that Pop Up window we call the Picker Tree Dialog.
I always wanted to create or use such functionality through custom code but didn't get chance to look in that.
Today I managed to create a custom web part which provides such functionality to end users. The main purpose for creation of such sample web part is to get to know how things happen behind the Picker Tee Dialog.
Thanks to these great posts which acted as a reference for me.
http://www.myrocode.com/post/2009/07/14/Using-PickerTreeDialog-in-SharePoint-2007-pages-with-postback-support.aspx
http://chrissyblanco.blogspot.com/2008/07/adding-sharepoint-site-picker-to_03.html
Basically every operation is handled in a JavaScript file such as opening of a pop up and after selecting an item in the pop up when you press OK button, then this post back handling is also handled in JS file.
There is a responsible JS to do this is located in the web front end server at location _layouts/(localeID)/PickerTreeDialog.js where localeID is something like 1033. So we need to refer to this file.
After clicking the Browse Button, a pop up opens and after we select an item and click ok then the selected value appears in the text box, and then this value can be used anywhere as needed; I am just displaying whatever is there in the text box after clicking the button.
There is a call back function in the JavaScript file which is responsible for handling the post back after clicking ok in the dialog.
A JavaScript function is called on the Client Click of the Browse Button and two parameters are passed; one is the server relative URL of the current web and the other is the Client ID of the text box.
So here are the related files:
1. web part class file
2. user control (.ascx file)
3. user control code behing
4. .js file
(I know .js file which I pasted can be improved but I haven't done thatJ)
1. web part class
public class PickerControl : WebPart
{
protected override void CreateChildControls()
{
base.CreateChildControls();
DemoPickerUC _control = this.Page.LoadControl(@"~/_ControlTemplates/DemoPicker/DemoPickerUC.ascx") as DemoPickerUC;
if (_control != null)
{
this.Controls.Add(_control);
}
}
}
2. User Control (.ascx)
<%@ Control AutoEventWireup="true" CodeBehind="DemoPickerUC.ascx.cs" Inherits="Sample.SharePoint.Picker.UC_Code.DemoPickerUC, Sample.SharePoint.Picker, Version=1.0.0.0, Culture=neutral, PublicKeyToken=6789391ffe13acb5" %>
<script type="text/javascript" src="/_layouts/1033/core.js"></script>
<script type="text/javascript" src="/_layouts/1033/PickerTreeDialog.js"></script>
<script type="text/javascript" src="/_layouts/Demo/LaunchPickerDemo.js"></script>
<asp:TextBox ID="textBox" runat="server"></asp:TextBox>
<asp:Button ID="browseButton" runat="server" Text="Browse" />
<asp:Button ID="postBackbtn" runat="server" Text="Click" />
3. User Control Code Behing
public class DemoPickerUC : UserControl
{
#region Protected Elements
protected TextBox textBox;
protected Button browseButton;
protected Button postBackbtn;
#endregion
#region Private Variables
private string _webUrl = string.Empty;
private string _clientId = string.Empty;
#endregion
#region Overrides - on Load
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
try
{
//Registering On Clik Event of Post Back Button
if (postBackbtn != null)
{
postBackbtn.Click += new EventHandler(postBackbtn_Click);
}
//Elevation done for end user If anonymous access is enabled on site
SPSecurity.RunWithElevatedPrivileges(delegate()
{
_webUrl = SPContext.Current.Web.ServerRelativeUrl;
});
if (textBox != null)
{
if (!Page.IsPostBack)
{
textBox.Text = string.Empty;
}
//getting textbox's Client ID - required in js
_clientId = textBox.ClientID;
if (browseButton != null)
{
//calling javascript and pssing dynamic parameters
browseButton.OnClientClick = "javascript:launchPicker('" + _webUrl + "','" + _clientId + "');return false;";
}
}
}
catch (Exception ex)
{
this.Controls.Add(new LiteralControl(string.Format("{0}-{1}", "Error", ex.Message)));
}
}
void postBackbtn_Click(object sender, EventArgs e)
{
this.Controls.Add(new LiteralControl(string.Format("{0}-{1}", textBox.Text, "Selected..")));
}
#endregion
}
4. js file / function
function launchPicker(serverURL,cliendIDtxt) {
var listURLField = document.getElementById(cliendIDtxt);
var defaultURL = "/";
var url = serverURL;
if (listURLField != null && listURLField != '') {
url = listURLField.value.substring(0, listURLField.value.lastIndexOf('/'));
}
//call back function
var callback = function(arr) {
if (arr == null || arr == undefined || arr[1] == null || arr[2] == null)
return;
lastSelectedListSmtPickerId = arr[0];
var listURL = '';
if (listURL.substring(listURL.length - 1) != '/') listURL = listURL + '/';
if (arr[1].charAt(0) == '/') arr[1] = arr[1].substring(1);
listURL = listURL + arr[1];
if (listURL.substring(listURL.length - 1) != '/') listURL = listURL + '/';
if (arr[2].charAt(0) == '/') arr[2] = arr[2].substring(1);
listURL = listURL + arr[2];
if (listURL != '' && listURL != null)
listURLField.value = listURL;
var siteURL = '';
if (siteURL.substring(listURL.length - 1) != '/') siteURL = siteURL + '/';
if (arr[1].charAt(0) == '/') arr[1] = arr[1].substring(1);
siteURL = siteURL + arr[1];
if (siteURL.substring(siteURL.length - 1) != '/') siteURL = siteURL + '/';
if (arr[2].charAt(0) == '/') arr[2] = arr[2].substring(1);
siteURL = siteURL + arr[2];
if (siteURL != '' && siteURL != null)
listURLField.value = siteURL;
//var site = arr[1];
//var list = arr[2];
//listURLField.value = '';
// listURLField.value = url + site + (site == '/' ? '' : '/') + list;
}
LaunchPickerTreeDialog("CbqPickerSelectListTitle", "CbqPickerSelectListTitle", "", "", url, null, "", "", "", 0, callback);
}