Creating a Modal Dialog "Chooser" Tool Part
This first Sharepoint-related post is a relatively complete example of how to create a custom web part with a custom tool part that uses a pop-up modal dialog (a “Web Dialog“) to choose a value and return it to the tool part. My sample uses a pretty silly example and only utilizes a combo box in the dialog. However, this could easily serve as the starting point for a much more sophisticated tool part, such as one that uses a treeview or any other control that can run on a web page and return a value through DHTML.
The sample is in C#, for no particular reason except that I like C#. :)
=====
Some Windows Sharepoint Services 2.0 or Sharepoint Portal Server 2003 customers/applications may require that a web part include a tool part that has the capability to pop up a modal dialog for the user to choose a value from. An example in the existing SPS UI would be the modal dialog that is raised when assigning an audience to a specific web part; the UI includes a link that opens a dialog that the user can choose from, and the value is returned to SPS.
This sample includes an additional step. The audiences example above does not return the value directly to the tool part, but uses the return value to directly set a property. This sample returns the dialog value to a HTML text box on the tool part, which can then be assigned to the associated web part by using fairly standard code behind the scenes.
The following steps assume the use of Web Part Templates for Visual Studio.NET, available for download from the MSDN Library online:
SharePoint Products and Technologies Templates: Web Part Templates for Visual Studio .NET
https://www.microsoft.com/downloads/details.aspx?FamilyId=CAC3E0D2-BEC1-494C-A74E-75936B88E3B5&displaylang=en
1) Create a new Web Part Library Project in VS.NET
Name it ToolPartOpener
2) Add a Web Part to the Project
Name it Chooser.cs
3) Copy-paste the entirety of the following code into Chooser.cs, replacing any and all pre-existing template code:
using System;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebPartPages;
namespace ToolPartOpener
{
[DefaultProperty("Text"),
ToolboxData("<{0}:Chooser runat=server></{0}:Chooser>"),
XmlRoot(Namespace="ToolPartOpener")]
public class Chooser : Microsoft.SharePoint.WebPartPages.WebPart
{
private const string defaultText = "";
private string text = defaultText;
[Browsable(false),
Category("Miscellaneous"),
DefaultValue(defaultText),
WebPartStorage(Storage.Personal),
FriendlyName("Text"),
Description("Text Property")]
public string Text
{
get
{
return text;
}
set
{
text = value;
}
}
/// <summary>
///This method gets the custom tool parts for this Web Part by overriding the
///GetToolParts method of the WebPart base class. You must implement
///custom tool parts in a separate class that derives from
///Microsoft.SharePoint.WebPartPages.ToolPart.
///</summary>
///<returns>An array of references to ToolPart objects.</returns>
public override ToolPart[] GetToolParts()
{
ToolPart[] toolparts = new ToolPart[3];
WebPartToolPart wptp = new WebPartToolPart();
CustomPropertyToolPart custom = new CustomPropertyToolPart();
//The following two tool parts are the default parts for a web part
toolparts[0] = wptp;
toolparts[1] = custom;
//A reference to the custom tool part being created
toolparts[2] = new ToolPartOpener.ChooserToolPart();
return toolparts;
}
/// <summary>
/// Render this Web Part to the output parameter specified.
/// </summary>
/// <param name="output"> The HTML writer to write out to </param>
protected override void RenderWebPart(HtmlTextWriter output)
{
output.Write("Current Value: " + SPEncode.HtmlEncode(Text));
}
}
}
4) Add a Tool Part to the Project
Name it ChooserToolPart.cs
5) Copy-paste the entirety of the following code into ChooserToolPart.cs, replacing any and all pre-existing template code:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebPartPages;
namespace ToolPartOpener
{
/// <summary>
/// Description of the toolpart. Override the GetToolParts method in your WebPart
/// class to invoke this toolpart. To establish a reference to the Web Part
/// the user has selected, use the ParentToolPane.SelectedWebPart property.
/// </summary>
public class ChooserToolPart: Microsoft.SharePoint.WebPartPages.ToolPart
{
private string sUniqueInputID;
private string sValue = "";
public ChooserToolPart()
{
//Set some properties and event handlers for the tool part
this.Title = "Chooser Tool Part";
this.Init += new EventHandler(InitFunc);
this.PreRender += new EventHandler(PreRenderFunc);
}
private void InitFunc(object sender, System.EventArgs e )
{
//Get a reference to the tool part's unique ID to use as form item identifiers
//Using a unique ID allows multiple instances per web part page
sUniqueInputID = "Input" + this.UniqueID;
}
private void PreRenderFunc(object sender , System.EventArgs e )
{
//Insert JScript on PreRender
RegisterChooserScript();
}
protected void RegisterChooserScript()
{
string sScriptKey = "ChooserScriptKey";
//The code below contatenates a string containing the JScript code
//JScript code opens a dialog window using showModalDialog() and puts
//the returnValue into a text input HTML element on the tool part page using the unique ID
string EmbeddedScriptFormat =
"<script language=jscript>function OpenChooserDialog(){";
EmbeddedScriptFormat +=
"var sReturnValue; ";
EmbeddedScriptFormat += "sReturnValue = window.showModalDialog";
EmbeddedScriptFormat += (\"/_layouts/ChooserDialog.htm\",\"\",\"dialogHeight:100px;";
EmbeddedScriptFormat += "dialogWidth:300px;status:no;help:no\");";
EmbeddedScriptFormat += "if(sReturnValue == undefined){;}else{";
EmbeddedScriptFormat += "window.document.all[\'" + sUniqueInputID + "\'].value = sReturnValue;}";
EmbeddedScriptFormat +=
"}</script>";
//Check if the script is currently registered, and register if it is not
if(!Page.IsClientScriptBlockRegistered(sScriptKey))
Page.RegisterClientScriptBlock(sScriptKey,
EmbeddedScriptFormat);
}
///<summary>
///This method is called by the ToolPane object to apply property changes to the selected Web Part.
///</summary>
public override void ApplyChanges()
{
ToolPartSaveProps();
}
private void ToolPartSaveProps()
{
//Get a reference to the web part associated with this tool part
ToolPane tpPane = this.ParentToolPane;
ToolPartOpener.Chooser wpChooser = (ToolPartOpener.Chooser)(tpPane.SelectedWebPart);
try
{
//Assign the returned value to the web part's Text property
sValue = Page.Request.Form[sUniqueInputID].ToString();
wpChooser.Text = sValue;
}
catch (Exception e)
{
wpChooser.Text = e.ToString();
}
}
/// <summary>
///If the ApplyChanges method succeeds, this method is called by the ToolPane object
///to refresh the specified property values in the toolpart user interface.
/// </summary>
public override void SyncChanges()
{
//SyncChanges() is not required in this instance; since showModalDialog() requires
//the use of client-side script, we'll be synching the values in client-side script as well
}
/// <summary>
///This method is called by the ToolPane object if the user discards changes to the selected Web Part.
/// </summary>
public override void CancelChanges()
{
}
/// <summary>
/// Render this tool part to the output parameter specified.
/// </summary>
/// <param name="output">The HTML writer to write out to </param>
protected override void RenderToolPart(HtmlTextWriter output)
{
//Get a reference to the web part associated with this tool part
ToolPane tpPane = this.ParentToolPane;
ToolPartOpener.Chooser wpChooser = (ToolPartOpener.Chooser)(tpPane.SelectedWebPart);
//Write the button input to the tool part page, calling client-side function which is registered in
//the RegisterChooserScript() function
output.Write("<br><input class='ms-SPButton' width=\"100\" value=\'Open\' type=button onclick=\"OpenChooserDialog();\" > ");
//Write the text input box that the client-side script targets for the return value.
//Value is set to the Text property of the associated web part
output.Write("<input type=\"text\" class=\"UserInput\" size=\"20\" id=\"" + sUniqueInputID + "\" name=\"" + sUniqueInputID + "\" value=\"" + wpChooser.Text.ToString() + "\">");
}
}
}
6) Add an HTML Page to the Project
Name it ChooserDialog.htm
7) Copy-paste the entirety of the following HTML and code into ChooserDialog.htm (in HTML view), replacing any and all pre-existing HTML and/or code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<script language=jscript>
function ReturnToPart()
{
window.returnValue = window.document.all["select1"].value;
window.close();
}
</script>
<title>Chooser Dialog</title>
</head>
<body>
<form name="form1" id="form1">
<p align="center">
<br>
<select id="select1" name="select1">
<option id="opt1" value="Elephant">Elephant</option>
<option id="opt2" value="Giraffe">Giraffe</option>
<option id="opt3" value="Zebra">Zebra</option>
</select>
<input type="Button" name="Button1" id="Button1" value="OK" onclick="jscript:ReturnToPart();">
</p>
</form>
</body>
</html>
8) Save the HTML page to an accessible, browseable location
Recommended deployment for the HTML page is on the server running SPS/WSS, in the LAYOUTS folder in the WSS directory structure, found in a path similar to the following.
x:\Program Files\Common Files\Microsoft Shared\web server extensions\60\TEMPLATE\LAYOUTS
9) Deploy the Web Part
Deploying Web Parts Using DWP files and Web Part Galleries
https://msdn.microsoft.com/library/en-us/spptsdk/html/smpxPkgDeployWP.asp?frame=true
10) Use the Tool Part and Dialog
Comments
Anonymous
July 09, 2004
Neat article !Anonymous
August 04, 2004
http://www.ixmx.netAnonymous
December 27, 2006
Great Code. Do you have a toolpart that uses a dropdown to select a item and postback use a selectedindexchanged event to load a gridview then a select button on the gridview to select a item. Trying one myself and not much luck. Thank youAnonymous
August 14, 2007
What are the necessary changes we need to make in the code if we are using Microsoft Visual Studio 2005 instead of MS Visual Studio .NET? What are the references we need to add in Visual Studio 2005? RegardsAnonymous
October 23, 2007
how can we add that toolpart template to the project can u give the url for download the toolpart template