Creating Custom Field Controls With Sitefinity Thunder
Hi
I have created Custom Field Controls for blog post With Sitefinity Thunder and register that control in sitefinity admin. This field is not saving in admin while entering content and click save button.
I am attaching three related controls, please inspect it and let me know if i have done anything wrong. Also please change the file and revert back to me if possible.
Its too urgent, kindly revert
Thanks Much
1.ContributorsField.ascx
Code below
<%@ Control %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sf" %>
<asp:Label ID="titleLabel" runat="servcontributorsControler" CssClass="sfTxtLbl" />
<asp:DropDownList ID="contributorsControl" runat="server" />
<sf:SitefinityLabel id="descriptionLabel" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfDescription" />
<sf:SitefinityLabel id="exampleLabel" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfExample" />
2.ContributorsField.cs
Code below
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web.UI;
using System.Web.UI.WebControls;
using Telerik.Sitefinity.Utilities.TypeConverters;
using Telerik.Sitefinity.Web.UI;
using Telerik.Sitefinity.Web.UI.Fields;
using Telerik.Sitefinity.Web.UI.Fields.Contracts;
using Telerik.Sitefinity.Model;
using Telerik.Sitefinity.DynamicModules;
using Telerik.Sitefinity.GenericContent.Model;
using Telerik.Sitefinity.DynamicModules.Model;
namespace CustomFieldControls.ContributorsField
/// <summary>
/// A simple field control used to save a string value.
/// Use the path to this class when you add the field control
/// CustomFieldControls.ContributorsField.ContributorsField
/// </summary>
[FieldDefinitionElement(typeof(ContributorsFieldDefinitionElement))]
public class ContributorsField : FieldControl
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="ContributorsField" /> class.
/// </summary>
public ContributorsField()
#endregion
#region Properties
protected override WebControl TitleControl
get
return this.TitleLabel;
protected override WebControl DescriptionControl
get
return this.DescriptionLabel;
protected override WebControl ExampleControl
get
return this.ExampleLabel;
protected override string LayoutTemplateName
get return "CustomFieldControls.ContributorsField.ContributorsField.ascx";
/// <summary>
/// Obsolete. Use LayoutTemplatePath instead.
/// </summary>
//protected override string LayoutTemplateName
//
// get
//
// return string.Empty;
//
//
/// <summary>
/// Gets the layout template's relative or virtual path.
/// </summary>
//public override string LayoutTemplatePath
//
// get
//
// if (string.IsNullOrEmpty(base.LayoutTemplatePath))
// return ContributorsField.layoutTemplatePath;
// return base.LayoutTemplatePath;
//
// set
//
// base.LayoutTemplatePath = value;
//
//
/// <summary>
/// Gets the reference to the label control that represents the title of the field control.
/// </summary>
/// <remarks>
/// This control is mandatory only in write mode.
/// </remarks>
protected internal virtual Label TitleLabel
get
return this.Container.GetControl<Label>("titleLabel", true);
/// <summary>
/// Gets the reference to the label control that represents the description of the field control.
/// </summary>
/// <remarks>
/// This control is mandatory only in write mode.
/// </remarks>
protected internal virtual Label DescriptionLabel
get
return Container.GetControl<Label>("descriptionLabel", true);
/// <summary>
/// Gets the reference to the label control that displays the example for this
/// field control.
/// </summary>
/// <remarks>
/// This control is mandatory only in the write mode.
/// </remarks>
protected internal virtual Label ExampleLabel
get
return this.Container.GetControl<Label>("exampleLabel", true);
/// <summary>
/// Gets the text box control.
/// </summary>
/// <value>The text box control.</value>
protected virtual DropDownList ContributorsControl
get
return this.Container.GetControl<DropDownList>("contributorsControl", true);
[TypeConverter(typeof(ObjectStringConverter))]
public override object Value
get
return this.ContributorsControl.SelectedItem.Value;
set
if (value != null)
this.ContributorsControl.SelectedItem.Value = value as string;
public string Text get; set;
#endregion
#region Methods
protected override void InitializeControls(GenericContainer container)
this.TitleLabel.Text = this.Title;
this.ExampleLabel.Text = this.Example;
this.DescriptionLabel.Text = this.Description;
List<DynamicContent> allItems = new List<DynamicContent>();
allItems = GetAllContributorItems().OrderBy(n => n.GetValue<string>("LastName")).ToList();
this.ContributorsControl.DataSource = allItems;
this.ContributorsControl.DataValueField = "Id";
this.ContributorsControl.DataTextField = "Title";
this.ContributorsControl.DataBind();
//this.ContributorsControl.SelectedItem.Value = (string)this.Value;
//this.ContributorsControl.Text = this.Text;
public IQueryable<DynamicContent> GetAllContributorItems()
var providerName = "dynamicProvider2";
DynamicModuleManager dynamicModuleManager = DynamicModuleManager.GetManager(providerName);
Type contributorsType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.Contributors.Contributors");
var myCollection = dynamicModuleManager.GetDataItems(contributorsType).Where(item => item.Status == ContentLifecycleStatus.Live && item.Visible == true);
return myCollection;
public override IEnumerable<ScriptDescriptor> GetScriptDescriptors()
List<ScriptDescriptor> descriptors = new List<ScriptDescriptor>();
ScriptControlDescriptor descriptor = base.GetScriptDescriptors().Last() as ScriptControlDescriptor;
if (this.ContributorsControl != null)
descriptor.AddComponentProperty("contributorsControl", this.ContributorsControl.ClientID);
//return new[] descriptor ;
descriptors.Add(descriptor);
return descriptors.ToArray();
//public override IEnumerable<ScriptReference> GetScriptReferences()
//
// List<ScriptReference> scripts = new List<ScriptReference>(base.GetScriptReferences());
// scripts.Add(new ScriptReference(ContributorsField.ScriptReference, typeof(ContributorsField).Assembly.FullName));
// return scripts;
//
public override void Configure(IFieldDefinition definition)
base.Configure(definition);
IContributorsFieldDefinition fieldDefinition = definition as IContributorsFieldDefinition;
if (fieldDefinition != null)
if (!string.IsNullOrEmpty(fieldDefinition.SampleText))
this.Text = fieldDefinition.SampleText;
#endregion
#region Private members
//public static readonly string layoutTemplatePath = "~/CustomFieldControls/" + typeof(ContributorsField).Namespace + ".ContributorsField.ascx";
//public static readonly string ScriptReference = typeof(ContributorsField).Namespace + ".ContributorsField.js";
#endregion
public override IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences()
var scripts = new List<ScriptReference>(base.GetScriptReferences())
new ScriptReference("CustomFieldControls.ContributorsField.ContributorsField.js", this.GetType().Assembly.FullName),
new ScriptReference("Telerik.Sitefinity.Web.UI.Fields.Scripts.FieldDisplayMode.js", "Telerik.Sitefinity"),
;
return scripts;
3.ContributorsField.js
code below
Type.registerNamespace("CustomFieldControls.ContributorsField");
CustomFieldControls.ContributorsField.ContributorsField = function (element)
CustomFieldControls.ContributorsField.ContributorsField.initializeBase(this, [element]);
this._element = element;
this._labelElement = null;
this._contributorsControl = null;
CustomFieldControls.ContributorsField.ContributorsField.prototype =
initialize: function ()
/* Here you can attach to events or do other initialization */
CustomFieldControls.ContributorsField.ContributorsField.callBaseMethod(this, "initialize");
,
dispose: function ()
/* this is the place to unbind/dispose the event handlers created in the initialize method */
CustomFieldControls.ContributorsField.ContributorsField.callBaseMethod(this, "dispose");
,
/* --------------------------------- public methods ---------------------------------- */
/* --------------------------------- event handlers ---------------------------------- */
/* --------------------------------- private methods --------------------------------- */
_getContributorsValue: function ()
if (this._contributorsControl)
return this._contributorsControl.get_value;
return null;
,
_clearContributors: function ()
if (this._contributorsControl != null)
this._contributorsControl.set_value(null);
,
/* --------------------------------- properties -------------------------------------- */
get_value: function ()
var val = this._getContributorsValue();
return val;
,
set_value: function (value)
this._clearContributors();
if (value !== undefined && value != null && this._contributorsControl != null)
this._contributorsControl.set_value(value);
this._value = value;
alert(value);
,
get_contributorsControl: function ()
return this._contributorsControl;
,
set_contributorsControl: function (value)
this._contributorsControl = value;
;
CustomFieldControls.ContributorsField.ContributorsField.registerClass("CustomFieldControls.ContributorsField.ContributorsField", Telerik.Sitefinity.Web.UI.Fields.FieldControl);
Hello Thomas,
Thank you for contacting us.
I checked the source code that you sent us, but unfortunately I could not recreate your custom field on my side because you had sent us only some of the files that thunder generated for a field control. Also we don't know the structure of your custom module Contributor and what fields it have.
Investigating your source code, we see that you use field control to select a dynamic content item. We recommend using Related data in Sitefinity. Here is a link to the documentation of this feature:
http://www.sitefinity.com/documentation/documentationarticles/related-data-custom-field
You need to create a custom field for blog post and select Related data as Type of your custom field. Then from Data type dropdown you should select your Contributors module. You may choose from single or multiple selection. There is "Multiple items from this data type can be related" checkbox for this property.
Should you have any questions or experience issues, do not hesitate to contact us again.
Regards,
Miroslava
Telerik