Make your own Droplink control for the Sitecore Page Editor

Like I mentioned in previous post, How to make a customized control for the SitecorePageEditor,  there are some basic controls missing… One of them is the Droplink control.

So let’s make one 🙂

I have a page with a “typical” column layout, I want my widget/spot to be flexible so it can fit/span over one or many columns. In this case it’s a registration form.

Registration form spans over 2 columns
RegistrationWidgetColumn

Registration form spans over 1 column
RegistrationWidgetColumn1

In the Page Editor the column layout for the widget/spot is controlled with a dropdown.
RegistrationWidgetColumnPageEditor

In the Content Editor the item(registration form) has a droplink containing the column values.
ColumnSelected

The droplink contains a number of “column value” items, each “column value” has one “friendly value” and one “real value”.
The “real value” is the actual column value and the “friendly value” is what presents to the editor. In this case “1 column” is spanning over 4 columns
ColumnValue

The code for rendering the column span looks like this:

<div <%# !string.IsNullOrWhiteSpace(this.GetDataSourceOrContextItem().GetString(Sandbox.Identity.Constants.Fields.FooterTextSection.ColumnSelectorNumberOfColumns)) ? string.Format(@"class='col-md-{0}'", this.GetDataSourceOrContextItem().GetString(Sandbox.Identity.Constants.Fields.FooterTextSection.ColumnSelectorNumberOfColumns)) : string.Empty %>>

If you are wondering what the GetDataSourceOrContextItem is? It’s something I used from Brian Pedersen’s blog, http://briancaos.wordpress.com/2013/09/13/avoid-the-use-of-sitecore-context-item/.
(GetDropLinkSelectedItem and GetString are also extension methods)

Now it’s time to make the Droplink control for the Page Editor. The column layout for the widget/spot is controlled with a dropdown. That’s what we are going to do. But first I’ll do a dirty version.

<div  runat="server" visible="<%# Sitecore.Context.PageMode.IsPageEditorEditing %>">
    <span style="font-size: x-small">Number of columns it will span over</span>
    <select onchange=" var itemUri = new Sitecore.ItemUri('<%# this.GetDataSourceOrContextItem().ID.ToShortID() %>',
        '<%# this.GetDataSourceOrContextItem().Language.ToString() %>',
        '<%# this.GetDataSourceOrContextItem().Version.ToString() %>',
        '<%# new ID(this.GetDataSourceOrContextItem()[FieldIDs.Revision]).ToShortID() %>');
        Sitecore.WebEdit.setFieldValue(itemUri,
        '<%# Sandbox.Identity.Constants.Fields.FooterTextSection.ColumnSelectorNumberOfColumns.ToShortID() %>',
        this.options[this.selectedIndex].value);">
        <option value="" <%# string.IsNullOrWhiteSpace(this.GetDataSourceOrContextItem().GetString(Sandbox.Identity.Constants.Fields.FooterTextSection.ColumnSelectorNumberOfColumns)) ? "selected" : string.Empty   %>>No column</option>
        <option value="4" <%# this.GetDataSourceOrContextItem().GetString(Sandbox.Identity.Constants.Fields.FooterTextSection.ColumnSelectorNumberOfColumns).Equals("4") ? "selected" : string.Empty   %>>1 column</option>
        <option value="8" <%# this.GetDataSourceOrContextItem().GetString(Sandbox.Identity.Constants.Fields.FooterTextSection.ColumnSelectorNumberOfColumns).Equals("8") ? "selected" : string.Empty   %>>2 columns</option>
        <option value="12" <%# this.GetDataSourceOrContextItem().GetString(Sandbox.Identity.Constants.Fields.FooterTextSection.ColumnSelectorNumberOfColumns).Equals("12") ? "selected" : string.Empty   %>>3 columns</option>
    </select>
</div>

Previous post, How to make a customized control for the Sitecore Page Editor, explains what Sitecore.WebEdit.setFieldValue does.

Let’s redo the dirty version to a nice control. It will look like this when it’s finished.

<%@ Register TagPrefix="mycontrol" Namespace="Sandbox.Framework.Controls.PageEditor" Assembly="Sandbox.Framework.Controls" %>

<div runat="server" visible="<%# Sitecore.Context.PageMode.IsPageEditorEditing %>">
    <span style="font-size: x-small">Number of columns it will span over</span>
    <mycontrol:PageEditorDropLinkControl runat="server"
            DataSource="<%# this.GetDataSourceOrContextItem().ID %>"
            Field="<%# Sandbox.Newsletter.Constants.Fields.RegistrationForm.ColumnSelectorDropdown %>"
            EmptyText="No column"
            DropLinkItemTextField="<%# Sandbox.Design.Constants.Fields.DesignColumn.ColumnValueFriendly %>"
            DropLinkItemTemplate="<%# Sandbox.Design.Constants.Templates.DesignColumn %>"
            DropLinkItems="<%# Sandbox.Design.Model.Repositories.PageColumnRepository.PageColumnsSettingsItem().GetChildren()  %>" />

</div>

Finally! Here is the code for the “PageEditorDropLinkControl”

public class PageEditorDropLinkControl : FieldControl
{
    private readonly SafeDictionary<string> _parameters = new SafeDictionary<string>();


    public string EmptyText { get; set; }

    public ID DropLinkItemTextField { get; set; }

    public IEnumerable<Item> DropLinkItems { get; set; }

    public ID DropLinkItemTemplate { get; set; }

    protected override void DoRender(HtmlTextWriter output)
    {

        if (string.IsNullOrWhiteSpace(Field))
            throw new InvalidOperationException("Field property is required. All field web controls require the field name to be set.");

          
        FieldRenderer fieldRenderer = new FieldRenderer
        {
            Parameters = GetParameters(),
            DisableWebEditing = DisableWebEditing
        };


        StringBuilder stringBuilderOnChange = new StringBuilder();

        StringBuilder stringBuilderSelect = new StringBuilder();

        stringBuilderOnChange.AppendFormat(@"var itemUri = new Sitecore.ItemUri('{0}','{1}','{2}','{3}');", GetItem().ID.ToShortID(),
            GetItem().Language, GetItem().Version, new ID(GetItem()[FieldIDs.Revision]).ToShortID());

        stringBuilderOnChange.AppendFormat(@"Sitecore.WebEdit.setFieldValue(itemUri,'{0}',this.options[this.selectedIndex].value);", Field);

        stringBuilderSelect.AppendFormat(@"<select onchange=""{0}"" >", stringBuilderOnChange.ToString());
        stringBuilderSelect.AppendLine();
        stringBuilderSelect.AppendFormat(@"<option value='' {0} >{1}</option>", GetItem().GetDropLinkSelectedItem(new ID(Field)) == null ? "selected" : string.Empty, EmptyText);
        stringBuilderSelect.AppendLine();
            
        foreach (Item dropLinkItem in DropLinkItems.Where(dropLinkItem => dropLinkItem.IsDerived(DropLinkItemTemplate)))
        {
            stringBuilderSelect.AppendFormat(@"<option value='{0}' {1} >{2}</option>", dropLinkItem.ID, GetItem().GetDropLinkSelectedItem(new ID(Field)).ID.Equals(dropLinkItem.ID) ? "selected" : string.Empty, dropLinkItem.GetString(DropLinkItemTextField));
            stringBuilderSelect.AppendLine();
        }           

            
           
        stringBuilderSelect.AppendLine();
        stringBuilderSelect.Append("</select>");

        output.Write(stringBuilderSelect.ToString());


    }

    protected override Item GetItem()
    {
        if (this.Item != null)
            return this.Item;

        return !string.IsNullOrWhiteSpace(this.DataSource) ? Sitecore.Context.Item.Database.GetItem(this.DataSource) : base.GetItem();
    }

    private string GetParameters()
    {
        PopulateParameters(_parameters);
        return WebUtil.BuildQueryString(_parameters, false);
    }


}

That’s all for now folks 🙂


One thought on “Make your own Droplink control for the Sitecore Page Editor

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.