Create custom multiple choice field for BasicProfile using API; how to pass ChoiceItems
Hi,
I'm trying to add a number of custom fields to the sitefinity Basic Profile using the API (version 6.1).
As a starting point I used the samples provided here:
www.sitefinity.com/documentation/documentationarticles/developers-guide/sitefinity-essentials/modules/ecommerce/product-types/custom-fields/creating-custom-fields
Since these samples add customfields to ProductTypes I altered the code somewhat and up to this point I can succesfully add ShortText-, LongText-, Date-, Number- and YesNoFields.
The MultipleChoiceField however brings me two problems:
1. The ChoiceItems I pass to wcfField.Definition are not persisted; when I edit the custom field under Basic Profile, the default Choices (Choice 1, Choice 2 and Choice 3) are displayed in the Choices editor.
2. I'd like to enable Multiple Selection for this MultipleChoice field, so I choose Definition.RenderChoiceAs = RenderChoicesAs.CheckBoxes and Definition.AllowMultipleSelection = true. The control however is rendered as RadioButtons and is not Multiple Selectable.
Used procedure:
public static void CreateMultichoiceField(string fieldName, string fieldLabel)
var wcfField = new WcfField()
Name = fieldName,
ContentType = typeof(string).FullName,
FieldTypeKey = UserFriendlyDataType.MultipleChoice.ToString(),
IsCustom = true,
//Database mapping
DatabaseMapping = new WcfDatabaseMapping()
ClrType = typeof(string).FullName,
ColumnName = fieldName.ToLower(),
Nullable = true,
DbType = "VARCHAR",
,
//Field definition
Definition = new WcfFieldDefinition()
Title = fieldLabel,
FieldName = fieldName,
FieldType = typeof (ChoiceField).FullName,
;
var choiceItems = new List<
ChoiceItem
>();
var choiceItem = new ChoiceItem() Text = "Dutch", Value = "NL", Selected = false ;
choiceItems.Add(choiceItem);
choiceItem = new ChoiceItem() Text = "English", Value = "EN", Selected = false ;
choiceItems.Add(choiceItem);
choiceItem = new ChoiceItem() Text = "French", Value = "FR", Selected = false ;
choiceItems.Add(choiceItem);
choiceItem = new ChoiceItem() Text = "German", Value = "DE", Selected = false ;
choiceItems.Add(choiceItem);
var serializer = new JavaScriptSerializer();
wcfField.Definition.Choices = serializer.Serialize(choiceItems);
//wcfField.Definition.ChoiceDefinitions = ????????
//wcfField.Definition.ChoiceItemsTitles = ???????;
//wcfField.Definition.SelectedChoicesIndex = null;
wcfField.Definition.RenderChoiceAs = RenderChoicesAs.CheckBoxes;
wcfField.Definition.AllowMultipleSelection = true;
CustomFieldsContext.Validate(wcfField, TypeResolutionService.ResolveType("System.String"));
var typeContext = new CustomFieldsContext(TypeResolutionService.ResolveType("System.String").FullName);
typeContext.SaveFieldDefinition(wcfField, TypeResolutionService.ResolveType("System.String").Name, null);
typeContext.SaveChanges();
using (var metadataManager = MetadataManager.GetManager())
var metaType = metadataManager.GetMetaType("Telerik.Sitefinity.Security.Model", "SitefinityProfile");
var metaField = metadataManager.CreateMetafield(fieldName);
metaField.Title = fieldLabel;
CustomFieldsContext.SetFieldDatabaseMappings(metaField, metaType, UserFriendlyDataType.MultipleChoice, wcfField, metadataManager);
metaField.MetaAttributes.Add(new MetaFieldAttribute Name = "UserFriendlyDataType", Value = UserFriendlyDataType.MultipleChoice.ToString() );
metaField.MetaAttributes.Add(new MetaFieldAttribute Name = "IsCommonProperty", Value = "true");
metaType.Fields.Add(metaField);
metadataManager.SaveChanges();
SystemManager.RestartApplication(false);
Hi Herman,
First of all thanks for your patience. The investigation of the problem took a bit more time.
You are absolutely right about MultipleChoiceField problems. We have created a PITS issue and you can vote to increase its priority for fixing. Anyone who is interested could vote.
Currently there is a workaround in order to use a custom field with checkboxes wherever you prefer (the example is for Basic Profile). I'll give you the steps in the UI (they can be achieved with code).
I hope now you should be able to use the field as you expect.
Kind Regards,Hey DimBo,
The solution you descibe so detailed (addressing issue #2) works like a charm!
Thank you for this!
The Question now is how to implement this functionality in code, espacially now I have to deal with a UserFriendlyDataType (CustomMultipleChoice) that's not available in code. This is a bit of a problem since I reference UserFriendlyDataType.xxxx several times (see sample in original post).
Do I have to register it somewhere to have this custom typa available in code?
Next to this the question remains (issue #1) how to pass a list of ChoiceItem (List<ChoiceItem>) to the custom field when created through the API... after creation of the field the ChoiceItems seem to have dissappeared leaving me with onley the default choices (Choice 1, Choice 2 and Choice 3) :o(
Thanx!
Herman
Hello Herman,
For steps 1, 2 and 4 you can use the ConfigManager to update the configurations and that's all. But for step 3 (updating the SitefinityProfile) - you are right - you are not able to use UserFriendlyDataType
and call SetFieldDatabaseMappings
method. I hope in one of our next releases you will be able to use an overload with string instead of predefined enum. But you could do the job by yourself. You have to set metaField properties and that's it (ClrType, DBType, DBSqlType, DBLength, DBScale, Required, ColumnName, Index - some of them are optional).
And finally for the #1 question - it is done via configuration (as specified in step 4. - so you could modify it again with ConfigManager
ConfigManager mgr = ConfigManager.GetManager();
var contentViewConfig = mgr.GetSection<ContentViewConfig>();
//update content view controls you want
//contentViewConfig.ContentViewControls.
mgr.SaveSection(contentViewConfig);
DimBo,
First my apologies for my late reply; I've been working on something else pas few days.
Thank you for the feedbank on the ConfigManager; I'll experiment with this later today.
A question as a result of CustomMultipleChoice solution you presented me with earlier:
I repeated step 4 for all 7 views of the ProfileType_SitefinityProfile (from ViewFrontendCreate through ViewBackendOwnEdit).
When I edit/add a user in the backend underAdministration>User Management>Users, the CustomMultipleChoice works as expected; storing entered data and displaying it again when the users profile is reopend this way.
However, when I open the current users profile in the Backend (the Profile link next to the Logout lInk
in the upper right corner of the backend), the CustomMultipleChoice' TextBoxes are not rendered in View mode, only the Fields label is displayed.
In edit mode the Checkboxes are rendered, but do not reflect the data entered earlier.
When saving the profile after checking some CheckBoxes the following exception occurs:
Invalid cast from 'System.String' to 'System.String[]'.
What I'm I missing?
Thanx!
Grz. Herman
Hello Herman,
Thank you for getting back to us.
I suggest that the problem might come from the CustomMultipleChoice in the database. If it is stored as array of string (System.String[]), this error could occur. The built-in multiple choice value is stored as String, so try to modify in the settings as Dimitar described below.
Let me know if this helps resolving the problem.
Regards,
Yavor Slavchev
Telerik
Yavor,
Thanks for your reply.
I submitted a support ticket about this issue; so this thread can be considered closed.
Kind regards,
Herman P. Hartog