The technique for validating a SingleImagePlaceholderControl is similar to that of the HtmlPlaceholderControl.
We first need to find a way to read its contents using client-side
script. Once we have the content, we can proceed to check to see if it
is valid. If it isn’t, we cancel the save.
Let’s build a required SingleImagePlaceholderControl validator. In this example, we will program the validator to verify that the author has uploaded a picture to the control.
Retrieving the Value of the SingleImagePlaceholderControl
The SingleImagePlaceholderControl is rendered on the browser as a series of hidden form fields and images organized neatly within tables.
Here’s a snippet of the generated code:
. . . code continues . . .
<input type="hidden" value="" name="NCPH_ImagePlaceholderDefinitionName"
placeholderType="singleImage" />
<input type="hidden" value="" name="NCPHHRef_
ImagePlaceholderDefinitionName"/>
<input type="hidden" value="" name="NCPHAltText_
ImagePlaceholderDefinitionName"/>
<input type="hidden" value="" name="SingleImagePlaceholderControl1:
AuthoringModeControlsContainer:ImageEditControl" />
. . . code continues . . .
The
highlighted line shows the hidden form field that is used to store the
name of the image that has been uploaded. To get its value, we simply
use the following JavaScript:
<script language="javascript">
var fileName = document.all.NCPH_ImagePlaceholderDefinitionName.value;
</script>
The other hidden form fields contain the
alternate text and the hyperlink that the image points to when clicked.
The alternate text is held in the NCPHAltText_NameOfPlaceholderDefinition hidden field. The NCPHHRef_NameOfPlaceholderDefinition hidden field corresponds to the hyperlink. Replace the text NameOfPlaceholderDefinition with the name of the placeholder as defined in Template Explorer.
|
Checking for an Empty SingleImagePlaceholderControl
The NCPH_NameOfPlaceholderDefinition
field contains the path and filename of the uploaded image. It stores an
empty string when an image has not been uploaded to the placeholder
control. To determine whether or not the author has left it blank, we
will use the following JavaScript:
<script language="javascript">
function validateIDOfPlaceholder()
{
var fileName = document.all.NCPH_ImagePlaceholderDefinitionName.value;
if (filename == '')
{
return false;
}
else
{
return true;
}
}
</script>
The string IDOfPlaceholder will be
replaced with the actual ID of the placeholder control. In this way,
each placeholder control will have its own client-side validation
function.
The RequiredImagePHValidator
Let’s build the RequiredImagePHValidator. First, add a class file named RequiredImagePHValidator.cs to the MCMSValidator project.
Add the required namespaces above the namespace declaration.
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Text;
using Microsoft.ContentManagement.WebControls;
using Microsoft.ContentManagement.Publishing;
namespace MCMSValidation
{
}
As before, inherit from the BaseValidator class:
public class RequiredImagePHValidator: BaseValidator
{
}
Next, we inject the JavaScript function used for performing the client-side validation using the Page.RegisterClientScriptBlock() function within the overridden OnPreRender() method. The AddAttributesToRender() method wires the JavaScript to the evaluationfunction attribute. Add the following code directly below the RequiredImagePHValidator() constructor:
// register the client-side validation script
protected override void OnPreRender(System.EventArgs e)
{
base.OnPreRender(e);
// Add the script only in authoring mode.
if (WebAuthorContext.Current.Mode == WebAuthorContextMode.AuthoringNew
|| WebAuthorContext.Current.Mode == WebAuthorContextMode.AuthoringReedit)
{
string phName = "NCPH_";
if ((FindControl(this.ControlToValidate) == null)
|| !(FindControl(this.ControlToValidate) is SingleImagePlaceholderControl))
return;
phName +=
((SingleImagePlaceholderControl)FindControl(this.ControlToValidate) )
.BoundPlaceholder.Name;
StringBuilder sb = new StringBuilder();
sb.Append("<script language=\"javascript\">");
sb.Append("function validate" + this.ControlToValidate + "() \n");
sb.Append("{ \n");
sb.Append(" var fileName = document.all." + phName + ".value; \n");
sb.Append(" if (fileName == '') \n");
sb.Append(" { \n");
sb.Append(" return false; \n");
sb.Append(" } \n");
sb.Append(" else \n");
sb.Append(" { \n");
sb.Append(" return true; \n");
sb.Append(" } \n");
sb.Append("} \n");
sb.Append("</script>");
if (this.RenderUplevel && this.EnableClientScript)
{
if (!Page.IsClientScriptBlockRegistered("ReqImgPhValid_" + phName
+ "_ClientScript"))
{
Page.RegisterClientScriptBlock("ReqImgPhValid_"+phName+"ClientScript",
sb.ToString());
}
}
}
}
// wiring the client-side javascript to the Template File
protected override void AddAttributesToRender(
System.Web.UI.HtmlTextWriter writer)
{
base.AddAttributesToRender(writer);
if (this.RenderUplevel && this.EnableClientScript)
{
// perform validation only in authoring mode.
if (WebAuthorContext.Current.Mode == WebAuthorContextMode.AuthoringNew
|| WebAuthorContext.Current.Mode == WebAuthorContextMode.AuthoringReedit)
{
writer.AddAttribute("evaluationfunction", "validate"
+ this.ControlToValidate);
}
}
}
We want the ControlPropertiesValid() method to return true when the control to validate is a SingleImagePlaceholderControl. Add the following code below the AddAttributesToRender() method:
// get the validator to work with the SingleImagePlaceholderControl
protected override bool ControlPropertiesValid()
{
Control ctrl = FindControl(ControlToValidate);
if (ctrl != null)
{
return (ctrl is SingleImagePlaceholderControl);
}
else
{
return false;
}
}
Finally, we implement the EvaluateIsValid()
method. Although we have implemented exactly the same check using
client-side scripts, it’s always a good idea to repeat the check on the
server. Here, we check the ImageUrl property of the SingleImagePlaceholderControl. Validation passes only if an image has been uploaded to the placeholder control.
protected override bool EvaluateIsValid()
{
bool valid = true;
if (CmsHttpContext.Current.Mode == PublishingMode.Update)
{
SingleImagePlaceholderControl ctrl;
ctrl = FindControl(ControlToValidate) as SingleImagePlaceholderControl;
if (ctrl.ImageUrl == "")
{
valid = false;
}
}
return valid;
}
The control is complete. Save and build the project.