Adding Image Selector to Products Module
Hey folks,
Anyone have any sample code or some instructions for adding an image/album selector and a file/library selector to a custom module like the Products Module?
I notice that the ImageField looks promising, but hasn't been implemented yet. I've had no luck working with the FileFieldDefinitionElement as it fails requiring a value for "key".
The frustration here is just trying things a bit randomly without documentation.
I've read through:
www.sitefinity.com/.../creating_a_thumbnail_selector_for_news_items.aspx
Which also looks great. However, the question as to how to use that approach in a custom module wasn't answered in the comments.
Any sample code out there or anyone who knows how to bring this all together?
I apologize for the broad-sweeping request here, but my brain is a bit addled trying to sort through various code approaches to find an answer.
Thanks
- William
Hello William,
The blog post shows how to create a definition element and field control. So you need the filed control and the definition element which will be injected in your module.Your definition element should inherit from DefinitionConfigElement and you have to override GetDefinition method where you need to return your custom field. You should also implement an interface for the definition element that inherits from IDefinition and you have to implement the properties you need in the DefinitionConfigElement
All the best,
Ivan Dimitrov
the Telerik team
Thanks, Ivan,
I have to say, though, that your understanding how how your modules work, and the underlying code bases is much higher than mine. Is there any way of getting some sample code to see how you might inject these things into a custom control? Is there a blog post, some sample implementation, or documentation that would explain this in full?
I'm sure that would be of great benefit to other people trying to do this too.
If not, I'll go about the trial and error method and post back to the forum if I run into any issues.
Thanks again
- William
I second William. Is there a sample of this?
Yeah, Ivan,
There are just too many holes in there for me. Can't get this to implement in a custom control at all, mainly because I'm really confused as to how to merge this into the Products module, where files sit and how they fit together. Your response is intriguing, but I need more connecting-the-dots.
Any way you can provide any of the awesome sample code you are known for? :)
- William
Hi Ivan,
Please share some sample code that demonstrate how to do this with a Custom Module. I'm also stuck with this.
Thanks,
Duneel
Any Telerik update on this? I'm stuck at the exact same point in module development...
Hello Duneel,
Here is a sample
definition element
public class CustomFieldDefinitionElement : FieldControlDefinitionElement, ICustomFieldDefinition #region Constructors public CustomFieldDefinitionElement (ConfigElement parent) : base(parent) #endregion /// <summary> /// Gets the definition instance. /// </summary> /// <returns></returns> public override DefinitionBase GetDefinition() return new CustomFieldDefinition(this); #region ICustomFieldDefinition Members [ConfigurationProperty(PropertyNames.Rows, DefaultValue = 1)] [ObjectInfo(typeof(ConfigDescriptions), Title = "RowsCaption", Description = "RowsDescription")] public int Rows get return (int)this[PropertyNames.Rows]; set this[PropertyNames.Rows] = value; [ConfigurationProperty(PropertyNames.HideIfValue)] [ObjectInfo(typeof(ConfigDescriptions), Title = "HideIfValueCaption", Description = "HideIfValueDescription")] public string HideIfValue get return (string)this[PropertyNames.HideIfValue]; set this[PropertyNames.HideIfValue] = value; [ConfigurationProperty(PropertyNames.ExpandableDefinition)] [ObjectInfo(typeof(ConfigDescriptions), Title = "ExpandableControlElementCaption", Description = "ExpandableControlElementDescription")] public ExpandableControlElement ExpandableDefinitionConfig get return (ExpandableControlElement)this[PropertyNames.ExpandableDefinition]; set this[PropertyNames.ExpandableDefinition] = value; public IExpandableControlDefinition ExpandableDefinition get return this.ExpandableDefinitionConfig; internal struct PropertyNames public const string Rows = "rows"; public const string HideIfValue = "HideIfValue"; public const string ExpandableDefinition = "expandableDefinition"; #endregion #region IFieldDefinition members public override Type DefaultFieldType get return typeof(CustomField); #endregion #region IDefinition Members public ConfigElement ConfigDefinition get throw new NotImplementedException(); #endregionpublic interface ICustomFieldDefinition : IFieldControlDefinition /// <summary> ///Gets or sets the number of rows displayed in a text box. /// </summary> /// <value>The rows.</value> int Rows get; set; /// <summary> /// Gets or sets the value which compared with the actual value of the Field, if equal hides the text. /// </summary> /// <value>The hide if value.</value> string HideIfValue get; set; IExpandableControlDefinition ExpandableDefinition get; public class CustomFieldDefinition: FieldControlDefinition, ITextFieldDefinition #region Constuctors /// <summary> /// Initializes a new instance of the <see cref="CustomFieldDefinition"/> class. /// </summary> public CustomFieldDefinition() : base() /// <param name="configDefinition">The config definition.</param> public CustomFieldDefinition(ConfigElement configDefinition) : base(configDefinition) #endregion #region Properties /// <value>The rows.</value> public int Rows get return this.ResolveProperty("Rows", this.rows); set this.rows = value; /// <summary> /// Gets or sets the value which compared with the actual value of the Field, if equal hides the text. /// </summary> /// <value>The hide if value.</value> public string HideIfValue get return this.ResolveProperty("HideIfValue", this.hideIfValue); set this.hideIfValue = value; /// <summary> /// Gets or sets the object that defines the expandable behavior of the hierarchical taxon field. /// </summary> /// <value></value> public IExpandableControlDefinition ExpandableDefinition get if (this.expandableDefinition == null) this.expandableDefinition = new ExpandableControlDefinition(); this.expandableDefinition.ControlDefinitionName = this.ControlDefinitionName; this.expandableDefinition.ViewName = this.ViewName; this.expandableDefinition.SectionName = this.SectionName; this.expandableDefinition.FieldName = this.FieldName; return this.expandableDefinition; set this.expandableDefinition = value; #endregion #region Private fields private IExpandableControlDefinition expandableDefinition; private int rows; private string hideIfValue; #endregion public class CustomField : FieldControl, IExpandableControl Hi Ivan,
I'm getting a "'Telerik.Sitefinity.Configuration.Config': static types cannot be used as return types" error on this:
public ConfigElement ConfigDefinition get throw new NotImplementedException(); Hi,
Can yo post the code of your definition element?
Kind regards,
Ivan Dimitrov
the Telerik team
Hi Ivan,
I haven't tried to implement your sample code (not sure what goes where honestly) but in reviewing it I don't see anything at all that seems to reference an Image Library or all Images in All Libraries? Am I misunderstanding something and this isn't actually sample code for adding an Image Selector to the Products Module (or any custom module for that matter). I'm sure you're busy with all kinds of things but a bit more guidance here would be greatly appreciated. (i.e. how would we define a specific album for users to select images from).
Regards,
Phill
NewsField is the name of my CustomField
var newsField = new NewsFieldElement(knowledgebaseRelationshipsSection.Fields) ID = "newsFieldControl", DataFieldName = "newsRelationships", DisplayMode = displayMode, CssClass = "sfContentField" ; knowledgebaseRelationshipsSection.Fields.Add(newsField);Hey Ivan,
Thanks for your example.
I think I may be starting to understand what goes where here, though it's taken me some time to piece it together. I'm with Phill though in not seeing how this adds on an Image Selector to the Products module. But I'm sure it's something I just can't connect from the information in front of me.
When I try to compile this, also, I get a:
The type or namespace name 'ConfigurationProperty' could not be found (are you missing a using directive or an assembly reference?)
I've run out of time and have to ship with a text-field-only version of modules, which isn't elegant, but gets the job done. But I'd love to see some actual code samples of how to put these things together. Is there any hope of seeing an expanded Products module with selectors as a sample in the Q1 update? Otherwise, most of us are left reading posts and blogs and hoping that by merging samples into each other, we'll get lucky.
Thanks
- William
Hello William,
I will create a definition control and post the sample here. I will try to do this during the weekend.
Kind regards,
Ivan Dimitrov
the Telerik team
Hi Ivan,
Is there any update on this?
Thanks,
Anton
Hi Anton ,
I was busy with the release task and did not manage to create the sample. Will discuss this with our documentation team, so they can prepare fully working sample shortly and put it in our dev manual.
Best wishes,
Ivan Dimitrov
the Telerik team
Hi Ivan,
Just wondering if you ever managed to create a sample? I think this would be very handy for one of the things I'm trying to work on.
Thank you
Regards
Byron
Hi ,
Here is the server side part of the code. I didn't have time to complete the entire client component
This sample uses RadMaskedTextBox control
1. Template of the definition control
<%@ Control Language="C#" %><%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %><%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sf" %><sf:ConditionalTemplateContainer ID="conditionalTemplate" runat="server"> <Templates> <sf:ConditionalTemplate Left="DisplayMode" Operator="Equal" Right="Read" runat="server"> <sf:SitefinityLabel id="titleLabel_read" runat="server" WrapperTagName="div" HideIfNoText="false" CssClass="sfTxtLbl"></sf:SitefinityLabel> <sf:SitefinityLabel id="textLabel_read" runat="server" WrapperTagName="div" HideIfNoText="false" CssClass="sfTxtContent"></sf:SitefinityLabel> <sf:SitefinityLabel id="descriptionLabel_read" runat="server" WrapperTagName="p" HideIfNoText="false" CssClass="sfDescription"></sf:SitefinityLabel> </sf:ConditionalTemplate> <sf:ConditionalTemplate Left="DisplayMode" Operator="Equal" Right="Write" runat="server"> <asp:Label ID="titleLabel_write" runat="server" CssClass="sfTxtLbl" /> <asp:LinkButton ID="expandButton_write" runat="server" OnClientClick="return false;" CssClass="sfOptionalExpander" /> <asp:Panel ID="expandableTarget_write" runat="server" CssClass="sfFieldWrp"> <telerik:RadMaskedTextBox ID="textBox_write" runat="server" SelectionOnFocus="SelectAll" Label="IP address: " PromptChar="_" Width="300px" Mask="<0..255>.<0..255>.<0..255>.<0..255>"> </telerik:RadMaskedTextBox> <sf:SitefinityLabel id="descriptionLabel_write" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfDescription" /> <sf:SitefinityLabel id="exampleLabel_write" runat="server" WrapperTagName="div" HideIfNoText="true" CssClass="sfExample" /> </asp:Panel> </sf:ConditionalTemplate> </Templates></sf:ConditionalTemplateContainer>using System;using System.Collections.Generic;using System.Linq;using System.Text;using Telerik.Sitefinity.Web.UI.Fields.Contracts;using Telerik.Sitefinity.Web.UI.Extenders.Contracts; namespace Telerik.Sitefinity.Samples1 public interface IRadMaskedDefinition : IFieldControlDefinition string HideIfValue get; set; IExpandableControlDefinition ExpandableDefinition get; RadMaskedFieldDefinition using System;using System.Collections.Generic;using System.Linq;using System.Text;using Telerik.Sitefinity.Web.UI.Fields.Definitions;using Telerik.Sitefinity.Configuration;using Telerik.Sitefinity.Web.UI.Extenders.Contracts;using Telerik.Sitefinity.Web.UI.Extenders.Definitions;namespace Telerik.Sitefinity.Samples1 public class RadMaskedFieldDefinition : FieldControlDefinition, IRadMaskedDefinition public RadMaskedFieldDefinition() : base() public RadMaskedFieldDefinition(ConfigElement configDefinition) : base(configDefinition) #region IRadMaskedDefinition Members public string HideIfValue get return this.ResolveProperty("HideIfValue", this.hideIfValue); set this.hideIfValue = value; public IExpandableControlDefinition ExpandableDefinition get if (this.expandableDefinition == null) this.expandableDefinition = new ExpandableControlDefinition(); this.expandableDefinition.ControlDefinitionName = this.ControlDefinitionName; this.expandableDefinition.ViewName = this.ViewName; this.expandableDefinition.SectionName = this.SectionName; this.expandableDefinition.FieldName = this.FieldName; return this.expandableDefinition; set this.expandableDefinition = value; #endregion private IExpandableControlDefinition expandableDefinition; private string hideIfValue; using System;using System.Collections.Generic;using System.Linq;using System.Text;using Telerik.Sitefinity.Web.UI.Fields;using Telerik.Sitefinity.Web.UI;using System.Web.UI.WebControls;using Telerik.Sitefinity.Web.UI.Fields.Enums;using System.Web.UI;using Telerik.Web.UI;using Telerik.Sitefinity.Web.UI.Extenders;using Telerik.Sitefinity.Web.UI.Fields.Config;namespace Telerik.Sitefinity.Samples1 [FieldDefinitionElement(typeof(RadMaskedFieldDefinitionElement))] public class RadMaskedField : FieldControl, IExpandableControl public RadMaskedField() : base() this.LayoutTemplatePath = ControlUtilities.ToVppPath("Telerik.Sitefinity.Samples1.Resources.RadMaskedField.ascx"); protected override System.Web.UI.WebControls.WebControl DescriptionControl get return this.DescriptionLabel; protected override System.Web.UI.WebControls.WebControl ExampleControl get return this.TitleLabel; protected override System.Web.UI.WebControls.WebControl TitleControl get return this.ExampleLabel; protected override void InitializeControls(Web.UI.GenericContainer container) this.TitleLabel.Text = this.Title; this.DescriptionLabel.Text = this.Description; protected internal virtual Label TitleLabel get if (this.DisplayMode == FieldDisplayMode.Read) return this.Container.GetControl<Label>("titleLabel_read", true); else return this.Container.GetControl<Label>("titleLabel_write", true); protected internal virtual Label DescriptionLabel get if (this.DisplayMode == FieldDisplayMode.Read) return this.Container.GetControl<Label>("descriptionLabel_read", true); else return this.Container.GetControl<Label>("descriptionLabel_write", true); protected internal virtual Label ExampleLabel get if (this.DisplayMode == FieldDisplayMode.Write) return this.Container.GetControl<Label>("exampleLabel_write", true); else return this.Container.GetControl<Label>("exampleLabel_read", false); protected internal virtual RadMaskedTextBox TextBoxControl get if (this.DisplayMode == FieldDisplayMode.Write) return this.Container.GetControl<RadMaskedTextBox>(RadMaskedField.textBoxId, true); else return this.Container.GetControl<RadMaskedTextBox>("textBox_read", false); protected override string LayoutTemplateName get return null; public override IEnumerable<ScriptDescriptor> GetScriptDescriptors() //Dictionary<string, string> conditionDict = GetIDDictionary(); var descriptors = new List<ScriptDescriptor>(); if (this.DisplayMode == FieldDisplayMode.Write) descriptors.Add(this.GetExpandableExtenderDescriptor(this.ClientID)); var descriptor = this.GetBaseScriptDescriptors().Last() as ScriptControlDescriptor; if (this.TextBoxControl != null) descriptor.AddElementProperty("textBoxElement", this.TextBoxControl.ClientID); descriptor.AddProperty("_textBoxId", RadMaskedField.textBoxId); descriptor.AddProperty("_textLabelId", RadMaskedField.textLabelId); descriptors.Add(descriptor); return descriptors.ToArray(); public override IEnumerable<ScriptReference> GetScriptReferences() var assemblyFullName = typeof(TextField).Assembly.FullName; var scripts = new List<ScriptReference>(base.GetScriptReferences()); if (this.DisplayMode == FieldDisplayMode.Write) scripts.Add(this.GetExpandableExtenderScript()); var textScript = new ScriptReference(RadMaskedField.textFieldScript, assemblyFullName); scripts.Add(textScript); var fieldDisplayModeScript = new ScriptReference(RadMaskedField.fieldDisplayModeScript, assemblyFullName); scripts.Add(fieldDisplayModeScript); return scripts; public virtual IEnumerable<ScriptDescriptor> GetBaseScriptDescriptors() return base.GetScriptDescriptors(); private const string textBoxId = "textBox_write"; private const string textLabelId = "textLabel_read"; private const string textFieldScript = "Telerik.Sitefinity.Samples1.Resources.RadMaskedField.js"; private const string fieldDisplayModeScript = "Telerik.Sitefinity.Samples1.Resources.FieldDisplayMode.js"; private bool? expanded = true; #region IExpandableControl Members public WebControl ExpandControl get; set; public WebControl ExpandTarget get throw new NotImplementedException(); public string ExpandText get; set; public bool? Expanded get return this.expanded; set this.expanded = value; #endregion Type.registerNamespace("Telerik.Sitefinity.Samples1");Telerik.Sitefinity.Samples1.FieldDisplayMode = function() /// <summary> /// Represents the different client side work modes /// </summary>;Telerik.Sitefinity.Samples1.FieldDisplayMode.prototype = Read: 0, Write: 1 Telerik.Sitefinity.Samples1.FieldDisplayMode.registerEnum("Telerik.Sitefinity.Samples1.FieldDisplayMode");namespace Telerik.Sitefinity.Samples.Enums /// <summary> /// Defines the display mode of the field control. /// </summary> public enum FieldDisplayMode /// <summary> /// Display mode for reading the data of the field control. /// </summary> Read = 0, /// <summary> /// Display mode for writing (editing) the data of the field control. /// </summary> Write = 1 Hi,
I am guessing by the lacking of number of responses and "thank you" posts that readers simply didn't understand what you posted. Rather than letting your good work go to waste, please could you tone down your sample codes further for simplings like me and post a zip file of the project so I know which bit goes where? To me, this is rocket science, you have given really valuable pieces of material but you forget we aren't all rocket scientists and do not know how to put the simplest of things together.
Thank you for your hard work (especially over weekends).
R
Hello Richard,
Slavo has created a blog post that discuss creating a custom fields which explains some of the based classes.. You can take a look at this post to gather some more information. I agree that this part of the development is not well covered, so we will create a task for it an I hope to include it after Q2 release.
Best wishes,
Ivan Dimitrov
the Telerik team
if you reset the products catalog in the sdk to get the updated one it has a photo selector in it now :)