Retrieving Saved Content
When the posting is opened for editing, the
textbox of the date time picker control shows the previously saved date
and time value. For new postings, there won’t be a previous selection;
we will just use the current date and time. Override LoadPlaceholderContentForAuthoring():
protected override void LoadPlaceholderContentForAuthoring
(PlaceholderControlEventArgs e)
{
EnsureChildControls();
try
{
if (WebAuthorContext.Current.Mode == WebAuthorContextMode.AuthoringNew)
{
// The default value of the control is the current date and time
txtAuthoring.Text = DateTime.Now.ToString("dd MMM yyyy HH:mm");
}
else
{
txtAuthoring.Text = ((HtmlPlaceholder)this.BoundPlaceholder).Text;
}
}
catch(Exception ex)
{
lblMessage.Text = "Failed to load placeholder content: " + ex.Message;
}
}
Saving the Date and Time
When the posting is saved, we read the value stored in the TextBox and write it to the underlying HtmlPlaceholder. Any exceptions are trapped using a try-catch block and the detailed error message appears on screen. Add the overridden SavePlaceholderContent() method to the code:
protected override void SavePlaceholderContent(PlaceholderControlSaveEventArgs e)
{
EnsureChildControls();
try
{
((HtmlPlaceholder)this.BoundPlaceholder).Html = txtAuthoring.Text;
}
catch(Exception ex)
{
lblMessage.Text = ex.Message;
}
}
Validating the Date and Time
To ensure that only valid dates are saved, we will override the OnSavingContent()
method. We check to see if the value to be saved is a valid date by
attempting to convert the string stored in the TextBox to a DateTime
object. If it is a valid date, we won’t get an exception. Otherwise, we
catch the exception and the save operation can be canceled.
protected override void OnSavingContent(PlaceholderControlSavingEventArgs e)
{
try
{
DateTime.Parse(txtAuthoring.Text.Trim());
base.OnSavingContent(e);
// Clear any messages on the screen
lblMessage.Text = "";
}
catch(Exception ex)
{
e.Cancel = true;
lblMessage.Text = ex.Message;
}
}
Presenting the Selected Date and Time
In presentation mode, the selected date and time are displayed on the screen in a Label control. Let’s override the CreatePresentationChildControls() method and add a Label control to the presentation container.
private Label lblPresentation;
protected override void CreatePresentationChildControls
(BaseModeContainer presentationContainer)
{
lblPresentation = new Label();
presentationContainer.Controls.Add(lblPresentation);
}
The previously saved date and time value in the underlying HtmlPlaceholder is retrieved from the content repository and displayed in the Label control loaded earlier. Add the overridden LoadPlaceholderContentForPresentation() method as shown:
protected override void LoadPlaceholderContentForPresentation
(PlaceholderControlEventArgs e)
{
EnsureChildControls();
try
{
lblPresentation.Text = ((HtmlPlaceholder)this.BoundPlaceholder).Text;
}
catch(Exception ex)
{
lblPresentation.Text = ex.Message;
}
}
The date-time picker placeholder control is complete. Next, let’s build the dialog for selecting the date and time.
The Date and Time Picker Dialog
The Date and Time picker dialog contains:
- An ASP.NET Calendar control for choosing the date
- Two DropDownList controls, one for selecting the hour, another for the minute
- A Button control for setting the date and time value
Add a Web Form named DateTimePicker.aspx to the MCMS web project (in this example, we have added it to the Dialogs folder of the Tropical Green project). Ensure that the Page Layout property is changed to FlowLayout. Now toggle to HTML view and add the following headers to the form:
. . . code continues . . .
<form id="DateTimePicker" method="post" runat="server">
<b>Pick Date:</b>
<hr>
<b>Pick Time</b>
<hr>
</form>
. . . code continues . . .
Switch back to Design view. Drag and drop the following controls onto the Web Form and arrange them as shown opposite.
Control | Property | Property Value |
---|
Calendar | ID | Calendar1 |
DropDownList | ID | ddlHour |
DropDownList | ID | ddlMinute |
Button | ID | btnOK |
| Text | OK |
| Width | 100px |
Double-click on the form to get to the code-behind file. Within the Page_Load() event handler, we retrieve the previously selected date and time from the InitialValue
query string parameter. If for some reason (maybe the TextBox was
empty), the parameter doesn’t contain a valid date and time, we use the
current date and time instead.
private void Page_Load(object sender, System.EventArgs e)
{
if(!Page.IsPostBack)
{
// Retrieve the previously saved date and time
DateTime initialDate;
try
{
initialDate = DateTime.Parse(Request.QueryString["InitialValue"]
.ToString());
}
catch
{
// No previously saved date and time found.
// Use the current date and time.
initialDate = DateTime.Now;
}
}
}
The previously selected date and time is used to
initialize the Calendar control and the two drop-down lists that make up
the hour and minute of the selected time. In the Page_Load() event handler, we also fill in the hour and the minute dropdowns.
private void Page_Load(object sender, System.EventArgs e)
{
if (!Page.IsPostBack)
{
. . . code continues . . .
Calendar1.SelectedDate = initialDate;
Calendar1.VisibleDate = initialDate;
// fill up the dropdown list for hours
for (int i=0; i <= 23; i++)
{
ListItem li = new ListItem();
li.Text = i.ToString("00");
if (initialDate.ToString("HH") == li.Text)
{
li.Selected = true;
}
ddlHour.Items.Add(li);
}
// fill up the dropdown list for minutes
for (int i=0; i <= 59; i++)
{
ListItem li = new ListItem();
li.Text = i.ToString("00");
if (initialDate.ToString("mm") == li.Text)
{
li.Selected = true;
}
ddlMinute.Items.Add(li);
}
}
}
Toggle back to Design view and double-click on the OK button to get to the btnOK_Click()
event handler. Here, we will generate the client-side script that
passes the selected date and time value back to the calling control. The
calling control is retrieved from the CallingControl query
string parameter. Earlier, we have set this to contain the ID of the
TextBox used by the date-time picker placeholder control.
To write the selected date and time, we retrieve
the values of the Calendar control and of the hour and minute drop-down
lists. Using a JavaScript call, we write the value to the TextBox.
private void btnOK_Click(object sender, System.EventArgs e)
{
string callingControl = Request.QueryString["CallingControl"];
System.Text.StringBuilder script = new System.Text.StringBuilder();
script.Append("<script language=\"javascript\">");
script.Append("window.opener.document.all." + callingControl + ".value='"
+ Calendar1.SelectedDate.ToString("dd MMM yyyy") + " "
+ ddlHour.SelectedItem.Value + ":"
+ ddlMinute.SelectedItem.Value
+ "';");
script.Append("window.close();");
script.Append("</script>");
Page.RegisterClientScriptBlock("PickDate",script.ToString());
}
And that completes the dialog. Save and build the solution.
While the dialog
works fine, I need a more portable control that can be used across
projects without having to recreate the Web Form each time I use the
control. What are my options?
To deploy the control across multiple projects, consider one of the following options:
1. | Create a folder within the /IIS_CMS/ folder and store the dialog there. As all MCMS web projects have a virtual directory named CMS mapped to the IIS_CMS folder, the path of the dialog would be /CMS/SubFolder/datetimepicker.aspx.
|
2. | You could follow the concept used by MCMS when deploying the /nr/
folder across all websites on the same computer by adding the folder
that contains the DateTimePicker control to each virtual website that
uses it.
|
3. | Alternatively, use the technique MCMS uses when deploying the /CMS/
folder to new MCMS template projects. Add the folder that contains the
DateTimePicker control to each template project that requires it. When
getting the path of the control from within the code, use the value
returned from Page.Request.ApplicationPath. To automate this
for new projects, you could create a new enterprise template for Visual
Studio .NET. For more information about creating and editing enterprise
templates, see http://msdn.microsoft.com/library/en-us/vsent7/html/vxoriEnterpriseTemplates.asp.
|
4. | Rewrite
the date time picker control so that the calendar, hour and minute drop
down menus are generated on the control itself. You can embed them
within a <div> tag and use client-side script to show them when the Pick Date button is clicked.
|
Adding the Placeholder Control to a Template File
To add the control to an MCMS project, you will have to add the component to the Toolbox:
- Right-click on the tab you wish to add the control to.
- Select Add/Remove Items and choose to add a .NET Framework Component.
- Select Browse... and select UsefulPlaceholderControls.dll. Click Open.
- Click OK to close the dialog and add the control(s) to the Toolbox.
Once the control has been added to the Toolbox,
you can drag and drop it onto a template file and set its properties as
you would with regular placeholder controls.
Go ahead; add the date-time picker placeholder control to an existing template file. Set the PlaceholderToBind property to an appropriate HtmlPlaceholderDefinition. Navigate to a posting that uses the template and edit it. You should see a textbox and a Pick Date button. Click on the Pick Date
button and select a date. Save the posting. Notice that the TextBox and
Button controls are replaced by a single Label showing the date and
time that you have selected.