The SingleAttachmentPlaceholderControl,
like the other placeholder controls, can’t be validated with the
default ASP.NET server-side validation controls. In this section, we
will build a custom validation control, named RequiredAttachmentPhValidator,
that checks to see if a file has been uploaded to the control. If no
attachments have been uploaded, the page will not be saved.
As before, we will first find out how to read off the content of the SingleAttachmentPlaceholderControl. We will then write the client-side JavaScript that will perform the checking to be used within our validator.
Stored Values of the SingleAttachmentPlaceholderControl
Let’s take a look at the generated code for the SingleAttachmentPlaceholderControl. Among the various elements that make up the code, the SingleAttachmentPlaceholderControl contains several key hidden form fields as highlighted below:
. . . code continues . . .
<table border="1" cellpadding="0" cellspacing="0">
<tr>
<td>
<input type="hidden" value="" name="NCPH_AttachmentPlaceholderDefinitionName"
placeholderType="singleAttachment" />
<input type="hidden" value=""
name="NCPHDispText_AttachmentPlaceholderDefinitionName"/>
<input type="hidden" value=""
name="SingleAttachmentPlaceholderControl1:AuthoringModeControlsContainer:
AttachmentEditControl" />
<input id="SingleAttachmentPlaceholderControl1_AuthoringModeControlsContainer
_AttachmentEditControl" name="NCPHAttach_AttachmentPlaceholderDefinition1"
size="25" value="No Attachment Set" readOnly="true" tabindex="-1" />
</td>
</tr>
</table>
. . . code continues . . .
The field named NCPH_AttachmentPlaceholderDefinitionName contains the path of the file that has been uploaded to the control. The next field, NCPHDispText_AttachmentPlaceholderDefinitionName, holds the display text.
To retrieve these values, we will use the following JavaScript:
<script language="javascript">
// get the file name
var fileName = document.all.NCPH_AttachmentPlaceholderDefinitionName.value;
// get the display text
var displayText =
document.all.NCPHDispText_AttachmentPlaceholderDefinitionName.value;
</script>
Checking for an Empty SingleAttachmentPlaceholderControl
Armed with the script that retrieves the value,
we can now check to see if a file has been uploaded to the control by
checking to see if the NCPH_AttachmentPlaceholderDefinitionName
contains an empty string. If it does, no file has been uploaded and the
validation fails. We will use the script below in our validator:
<script language="javascript">
function validateIDOfPlaceholder()
{
// get the file name
var fileName = document.all.NCPH_AttachmentPlaceholderDefinitionName.value;
if (filename == '')
{
return false;
}
else
{
return true;
}
}
</script>
The RequiredAttachmentPHValidator
We’ve already built two
custom validators, and this third one follows the familiar pattern.
We’ll dive straight into the code and just highlight the interesting
points.
Add a class file named RequiredAttachmentPHValidator.cs to the MCMSValidators project. Code it as shown below:
using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
using System.Text;
using Microsoft.ContentManagement.WebControls;
using Microsoft.ContentManagement.Publishing;
namespace MCMSValidators
{
public class RequiredAttachmentPHValidator : BaseValidator
{
public RequiredAttachmentPHValidator()
{
// nothing to do
}
// 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 SingleAttachmentPlaceholderControl))
return;
phName +=
((SingleAttachmentPlaceholderControl)
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("ReqAttPhValid_" + phName
+ "_ClientScript"))
{
Page.RegisterClientScriptBlock("ReqAttPhValid_" + 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);
}
}
}
// get the validator to work with the SingleAttachmentPlaceholderControl
protected override bool ControlPropertiesValid()
{
Control ctrl = FindControl(ControlToValidate);
if (ctrl != null)
{
return (ctrl is SingleAttachmentPlaceholderControl);
}
else
{
return false;
}
}
protected override bool EvaluateIsValid()
{
bool valid = true;
if (CmsHttpContext.Current.Mode == PublishingMode.Update)
{
// Check the AttachmentUrl property to see if the control is empty.
SingleAttachmentPlaceholderControl ctrl;
ctrl = FindControl(ControlToValidate) as
SingleAttachmentPlaceholderControl;
if (ctrl.AttachmentUrl == "")
{
valid = false;
}
}
return valid;
}
}
}
Examine the code and you will find that it is very similar to the previous two custom validation controls.
The JavaScript that checks to see if a file has been uploaded to the SingleAttachmentPlaceholderControl is injected into the template file within the OnPreRender() method.
The ControlPropertiesValid() method verifies that a control to be validated is indeed a SingleAttachmentPlaceholderControl.
Finally, the EvaluateIsValid() method performs a server-side check to see if the SingleAttachmentPlaceholderControl.AttachmentUrl
property contains a path to a file. If it doesn’t, the method returns
false. As in the previous examples, this method would probably not be
triggered as we are relying on client-side checks for validation. If you
need to perform server-side validation, you will have to create a
custom placeholder control as described in the section Implementing Server-Side Validation.