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();
#endregion
public
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 :)