using System;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Publishing.WebControls;
using Microsoft.SharePoint.Publishing.Fields;
namespace VZ.Controls.CustomFieldControls
/// A Field control that binds to fields of type LinkField and is
/// specialized to select and render embedded media files.
/// The RenderFieldForDisplay function generates the HTML markup to
/// display the media file. The MediaSelector control is
/// used at edit time to allow authors to select a media file in
/// the Asset Picker dialog box.
{
public class MediaPlayerFieldControl : BaseFieldControl
{
private MediaSelector mediaSelector = new MediaSelector();
public MediaPlayerFieldControl()
{
}
/// Gets and sets the value in the edit controls
public override object Value
{
get
{
LinkFieldValue mediaUrlValue = new LinkFieldValue();
mediaUrlValue.NavigateUrl =
this.mediaSelector.MediaUrl;
mediaUrlValue.Text =
LinkFieldValue.GetDefaultDisplayText(mediaUrlValue.NavigateUrl);
return mediaUrlValue;
}
set
{
LinkFieldValue mediaLinkFieldValue =
value as LinkFieldValue;
if (null != mediaLinkFieldValue)
{
this.mediaSelector.MediaUrl =
mediaLinkFieldValue.NavigateUrl;
}
else
{
this.mediaSelector.MediaUrl = String.Empty;
}
}
}
/// Get the default name used to find the template and
/// control for the MediaPlayerSelector in the control
/// template ASCX files.
protected override string DefaultTemplateName
{
get { return "MediaPlayerFieldControl"; }
}
private const string AllowExternalUrlsViewStateKey = "AllowExternalUrls";
/// A flag that determines whether to allow saving of external
/// media URLs.
public bool AllowExternalUrls
{
get
{
// Return true by default if not already in view state.
if (ViewState[AllowExternalUrlsViewStateKey] == null)
{
return true;
}
return (bool)ViewState[AllowExternalUrlsViewStateKey];
}
set
{
ViewState[AllowExternalUrlsViewStateKey] = value;
}
}
/// Creates the edit control when not in display mode.
protected override void CreateChildControls()
{
base.CreateChildControls();
if (this.ControlMode != SPControlMode.Display)
{
MediaSelector mediaSelectorInTemplate =
this.TemplateContainer.FindControl(this.TemplateName)
as MediaSelector;
if (null == mediaSelectorInTemplate)
{
// No media selector was found in the control
// template ASCX files. Add the default selector.
this.Controls.Add(this.mediaSelector);
}
else
{
// Get the media selector from the control
// template ASCX file.
mediaSelectorInTemplate.MediaUrl =
this.mediaSelector.MediaUrl;
this.mediaSelector = mediaSelectorInTemplate;
}
}
}
/// Gets the current value for the media URL as stored
/// in the list item.
private string itemFieldValueMediaUrl
{
get
{
LinkFieldValue currentLinkValue =
this.ItemFieldValue as LinkFieldValue;
if (null != currentLinkValue)
{
return currentLinkValue.NavigateUrl;
}
else
{
return String.Empty;
}
}
}
/// Renders the current list item value for the media URL
/// with embedded media player markup.
/// <param name="output"></param>
protected override void
RenderFieldForDisplay(System.Web.UI.HtmlTextWriter output)
{
if (!String.IsNullOrEmpty(this.itemFieldValueMediaUrl))
{
output.Write(MediaRenderingUtilities.GetMediaPlayerHtmlMarkup(this.itemFieldValueMediaUrl));
}
}
/// Verifies that the MediaUrl is valid.
public override void Validate()
{
base.Validate();
if (this.IsValid)
{
LinkFieldValue currentMediaUrlValue =
this.Value as LinkFieldValue;
if (currentMediaUrlValue ==
null || String.IsNullOrEmpty(currentMediaUrlValue.NavigateUrl))
{
// Ensure the field is not required.
if (this.Field != null && this.Field.Required)
{
this.IsValid = false;
this.ErrorMessage =
"This field is required and must contain a media file URL.";
return;
}
else
{
// The field is empty and not required.
// The data is valid.
return;
}
}
// Perform validation on the media file URL.
HtmlValidationContext validationContext =
new HtmlValidationContext();
if (!this.AllowExternalUrls)
{
// Restrict URLs to be either from the current site
// collection or server-relative.
validationContext.RestrictUrlsToSiteCollection = true;
validationContext.GuidOfThisSiteCollection =
SPContext.Current.Site.ID;
}
bool droppedTags;
bool droppedUrls;
LinkFieldValue validatedValue =
validationContext.ValidateLinkValue(
currentMediaUrlValue,
out droppedTags,
out droppedUrls);
if (droppedUrls || String.IsNullOrEmpty(validatedValue.NavigateUrl))
{
// The media file URL in the link field value was
// not valid so report the error message.
// Setting IsValid to false stops saving the page.
this.IsValid = false;
this.ErrorMessage =
"The URL for the media file was invalid.";
if (!this.AllowExternalUrls)
{
this.ErrorMessage +=
" You must select a URL within the current site collection.";
}
}
}
}
}
/// This edit control for the MediaPlayerFieldControl has
/// a toolbar and text box for selecting a media file URL.
/// This example intentionally uses a separate toolbar button
/// and text box for the AssetUrlSelctor to show a more complex
/// example. You can use an AssetUrlSelector control instead of
/// a TextBox child control, which displays its own browse button.
public class MediaSelector : WebControl
{
private TextBox mediaUrlTextBox = new TextBox();
public MediaSelector()
{
}
/// This is the media URL value that you can edit in the text
/// box or Asset Picker dialog box.
public string MediaUrl
{
get { return this.mediaUrlTextBox.Text; }
set { this.mediaUrlTextBox.Text = value; }
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
// This ensures that the TextBox child control receives
// its postback.
EnsureChildControls();
}
/// Gets JavaScript required to launch an Asset Picker dialog
/// box for choosing a media file URL.
private string GetAssetPickerButtonScript()
{
AssetUrlSelector mediaAssetSelector =
new AssetUrlSelector();
// When the AssetUrlSelector control is not added to the
// page control tree, the Page and ID properties are
// required because
// AssetUrlSelector.GetClientLaunchPickerReference()
// needs register script in the page.
mediaAssetSelector.Page = this.Page;
mediaAssetSelector.ID = "MediaUrlAssetSelector";
// Uses the TextBox client ID to connect the Asset Picker
// dialog box to the text box.
mediaAssetSelector.AssetUrlClientID =
this.mediaUrlTextBox.ClientID;
// Autopostback to see the new media file rendered after
// clicking OK on the Asset Picker dialog box.
mediaAssetSelector.AutoPostBack = true;
mediaAssetSelector.OverrideDialogTitle = "Select a media file";
mediaAssetSelector.OverrideDialogDescription =
"Select a media file to embed in this page";
mediaAssetSelector.UseImageAssetPicker = false;
return mediaAssetSelector.GetClientLaunchPickerReference();
}
private Literal mediaPlayerOutput = new Literal();
protected override void CreateChildControls()
{
SimpleToolbar mediaSelectorToolbar = new SimpleToolbar();
mediaSelectorToolbar.ID = "ToolBar";
this.Controls.Add(mediaSelectorToolbar);
Label mediaUrlLabel = new Label();
mediaUrlLabel.Text = "Selected media file URL: ";
mediaUrlLabel.AssociatedControlID = "MediaUrlTextBox";
this.Controls.Add(mediaUrlLabel);
this.mediaUrlTextBox.ID = "MediaUrlTextBox";
this.mediaUrlTextBox.CssClass =
"ms-input ms-lactiontable sample-mediaselector-urltextbox";
this.Controls.Add(this.mediaUrlTextBox);
// Add the button after the rest so that the text box
// ClientID is already determined and can be connected
// in the Asset Picker dialog box client script.
mediaSelectorToolbar.AddToolbarButton(
"SelectMediaFile",
"Select a media file",
this.GetAssetPickerButtonScript(),
"Open a picker to select a media file URL");
// Add a refresh button to perform a basic postback to
// to update the MediaUrl rendering.
mediaSelectorToolbar.AddToolbarButton(
"RefreshMediaFile",
"Refresh",
this.Page.ClientScript.GetPostBackEventReference(this,
String.Empty),
"Refresh the page to reload the current media file URL",
"/_layouts/IMAGES/refresh.gif");
// If there is a media file URL, this code creates
// the media player markup.
this.Controls.Add(this.mediaPlayerOutput);
}
protected override void OnPreRender(EventArgs e)
{
string mediaFileOutputHtml =
MediaRenderingUtilities.GetMediaPlayerHtmlMarkup(this.MediaUrl);
if (String.IsNullOrEmpty(mediaFileOutputHtml))
{
this.mediaPlayerOutput.Text =
"<BR>{There is no valid media file URL to display}<BR>";
}
else
{
this.mediaPlayerOutput.Text =
"<BR>" + mediaFileOutputHtml + "<BR>";
}
base.OnPreRender(e);
}
}
/// A simple toolbar class that matches the styles of the
/// publishing field control toolbars.
public class SimpleToolbar : RepeatedControls
{
public SimpleToolbar()
{
this.HeaderHtml =
"<div class=\"ms-toolbarContainer\" width=\"100%\">";
this.FooterHtml = "</div>";
this.SeparatorHtml = "";
}
public void AddToolbarButton(
string buttonId,
string buttonText,
string clientOnClick,
string tooltipText)
{
Literal buttonMarkupLiteral = new Literal();
buttonMarkupLiteral.Text = String.Format(
SimpleToolbarButtonHtmlFormat,
SPHttpUtility.HtmlEncode(buttonText),
SPHttpUtility.HtmlEncode(clientOnClick),
SPHttpUtility.HtmlEncode(tooltipText));
buttonMarkupLiteral.ID = buttonId;
this.Controls.Add(buttonMarkupLiteral);
}
public void AddToolbarButton(
string buttonId,
string buttonText,
string clientOnClick,
string tooltipText,
string buttonImageSrc)
{
Literal buttonMarkupLiteral = new Literal();
buttonMarkupLiteral.Text = String.Format(
SimpleToolbarButtonImageHtmlFormat,
SPHttpUtility.HtmlEncode(buttonText),
SPHttpUtility.HtmlEncode(clientOnClick),
SPHttpUtility.HtmlEncode(tooltipText),
SPHttpUtility.HtmlUrlAttributeEncode(buttonImageSrc));
buttonMarkupLiteral.ID = buttonId;
this.Controls.Add(buttonMarkupLiteral);
}
// {0} = Button text
// {1} = onclick script
// {2} = Tooltip text
private const string SimpleToolbarButtonHtmlFormat = @"
<DIV class=""ms-toolbarItem ms-selectorlink"">
<A href=""#"" onclick=""{1}"" title=""{2}""> {0}</A>
</DIV>";
// {0} = Button text
// {1} = onclick script
// {2} = Tooltip text
// {3} = Button image markup
private const string SimpleToolbarButtonImageHtmlFormat = @"
<DIV class=""ms-toolbarItem ms-selectorlink"">
<A href=""#"" onclick=""{1}"" title=""{2}"">
<IMG alt=""{2}"" src=""{3}"" border=""0"">{0}</A>
</DIV>";
}
public static class MediaRenderingUtilities
{
/// Take a media file URL and generate HTML markup
/// for playing the file.
/// <param name="mediaUrl"></param>
public static string GetMediaPlayerHtmlMarkup(string mediaUrl)
{
// HtmlUrlAttributeEncode returns an empty string if the
// URL protocol is not allowed (e.g., JavaScript:)
string encodedUrl =
SPHttpUtility.HtmlUrlAttributeEncode(mediaUrl);
if (String.IsNullOrEmpty(encodedUrl))
{
return String.Empty;
}
else
{
return String.Format(MediaPlayerHtmlMarkupFormat, encodedUrl);
}
}
// Currently, this code includes only a parameter for the media
// file URL, but it could also include parameters for the
// width, height, and other rendering properties from field
// control properties or authored data value properties.
private const string MediaPlayerHtmlMarkupFormat = @"
@"<object id=""MediaPlayer""
width=400 height=300
classid=""CLSID:22D6f312-B0F6-11D0-94AB-0080C74C7E95""
standby=""Loading Windows Media Player components...""
type=""application/x-oleobject""
codebase=""http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,7,1112"">
<param name=""filename"" value=""{0}"">
<param name=""Showcontrols"" value=""True"">
<param name=""autoStart"" value=""True"">
<embed type=""application/x-mplayer2""
src=""{0}"" name=""MediaPlayer""
width=400 height=300></embed>
</object>";}
} |