Creating Dynamic Type

Posted by Community Admin on 03-Aug-2018 00:23

Creating Dynamic Type

All Replies

Posted by Community Admin on 05-Nov-2010 00:00

Hello,


I am trying to create a simple question & answer module for Sitefinity 4 Beta 2. And I have created a new type to store questions and answers using Dynamic Type mentioned in the documentation (http://www.sitefinity.com/40/help/developer-manual/fluent-api-dynamic-data-dynamic-types.html).

I have two questions:
1, Am I going the right direction? 
2, After creating a dynamic type, how do I create and manipulate data?

Thanks,
Bill

Posted by Community Admin on 05-Nov-2010 00:00

Hi Bill,


There is a Fluent API facade that you can use DynamicFieldFacade  and its methods. For instance to create a new dynamic field you can use

CreateNew(string fieldName, Type fieldType) - Creates a new instance of the "MetaField" with the specified field name and type.

fieldName - The name of the new dynamic field
fieldType - The type of the new dynamic field.

There are methods in the standard API where you have to use MetadataManager

MetaField field;
var metaMan = initializer.Context.MetadataManager;
// itemType is System.Type object or you can use a custom object
var type = metaMan.GetMetaType(itemType);
if (type == null)
    type = metaMan.CreateMetaType(itemType);
  
var result = metaMan.GetMetafields().SingleOrDefault(f => f.FieldName == "MyCustomField");
if (result == null)
    field = metaMan.CreateMetafield("MyCustomField");
       
    type.Fields.Add(field);


You can use Field controls to get /set the data of your custom fields.

sample

<%@ Control Language="C#" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI" TagPrefix="sf" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.FieldControls" TagPrefix="sfFields" %>
<%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.Fields" TagPrefix="sfFields" %>
   
<sfFields:FormManager ID="formManager" runat="server" />
   
<sitefinity:TextField
    ID="StudentName"
    runat="server"
    DataFieldName="StudentName"
    DisplayMode="Write"
    CssClass="sfSettingsSection"
    Title="<%$Resources:Labels, StudentName%> " />
  
<p class="sfButtonArea">                      
    <asp:HyperLink id="btnSave" runat="server" class="sfLinkBtn sfSave">
        <strong class="sfLinkBtnIn"><asp:Literal ID="Literal5" runat="server" Text='<%$ Resources:Labels, SaveChangesLabel %>' /></strong>
    </asp:HyperLink>
</p>


You can reuse the FieldControlsBinder and set your custom web service that will get, save,  sort etc your data.

<sfFields:FieldControlsBinder ID="fieldsBinder" runat="server" TargetId="fieldsBinder" DataKeyNames="Id" ServiceUrl=" here set the path to your WCF service that has methods for getting, setting etc content">
</sfFields:FieldControlsBinder>


If your module is going to work with ContentItem objects you can use ContentService or create a custom class that inherits from ContentService.

The better option is using module definition

protected override void InstallPages(SiteInitializer initializer)
    
        .... 
           ....
  
         if (landingPage == null)
        
            var pageInfo = new PageDataElement()
            
                PageId = this.LandingPageId,
                Name = "CustomModule",
                MenuName = "CustomModuleTitle",
                UrlName = "CustomModuleUrlName",
                Description = "CustomModuleDescription",
                HtmlTitle = "CustomModuleHtmlTitle",
                ResourceClassId = ResourceClassId,
                IncludeScriptManager = true,
                ShowInNavigation = false,
                EnableViewState = false,
                TemplateName = SiteInitializer.BackendTemplateName
            ;
            pageInfo.Parameters["ModuleName"] = CustomModule.ModuleName;
            var controlPanel = new BackendContentView()
            
                ModuleName = CustomModuleModule.ModuleName,
                ControlDefinitionName = CustomModuleCustomModuleDefinition.BackendDefinitionName
            ;
            initializer.CreatePageFromConfiguration(pageInfo, customNode, controlPanel);
        
  
    


definition

namespace Telerik.Sitefinity.Modules.CustomModule
    /// <summary>
    /// This is a static class used to initialize the properties for all ContentView control views
    /// of supplied by default for the CustomModule.
    /// </summary>
    internal static class CustomModuleCustomModuleDefinition
    
        #region Backend CustomModuleDefinition
        static CustomModuleCustomModuleDefinition()
        
            // Ensure CustomModule module is initialized.
            SystemManager.GetApplicationModule(CustomModule.ModuleName);
        
  
        /// <summary>
        /// Defines the ContentView control for CustomModule on the backend
        /// </summary>
        /// <param name="parent">The parent configuration element.</param>
        /// <returns>A configured instance of <see cref="ContentViewControlElement"/>.</returns>
        internal static ContentViewControlElement DefineCustomModuleBackendContentView(ConfigElement parent)
        
            // define content view control
            var backendContentView = new ContentViewControlElement(parent)
            
                ControlDefinitionName = BackendDefinitionName,
                ContentType = typeof(MyContentItem)
            ;
  
            // *** define views ***
  
            #region CustomModule backend list view
  
            // this is our list view where we are going to use RadGrid control
            var CustomModuleGridView = new MasterGridViewElement(backendContentView.ViewsConfig)
            
                ViewName = CustomModuleCustomModuleDefinition.BackendListViewName,
                ViewType = typeof(MasterGridView),
                AllowPaging = true,
                DisplayMode = FieldDisplayMode.Read,
                ItemsPerPage = 50,
                ResourceClassId = typeof(CustomModuleResources).Name,
                SearchFields = "Title",
                SortExpression = "Title ASC",
                Title = "CustomModuleTitle",
                WebServiceBaseUrl = "~/Sitefinity/Services/Content/CustomModuleItemService.svc/"
            ;
  
            #region Toolbar definition
  
            WidgetBarSectionElement masterViewToolbarSection = new WidgetBarSectionElement(CustomModuleGridView.ToolbarConfig.Sections);
  
            var createCustomModuleWidget = new CommandWidgetElement(masterViewToolbarSection.Items)
            
                Name = "CreateCustomModuleWidget",
                ButtonType = CommandButtonType.Create,
                CommandName = CustomModuleDefinitionHelper.CreateCommandName,
                Text = "CreateItem",
                ResourceClassId = typeof(CustomModuleResources).Name,
                CssClass = "sfMainAction",
                WidgetType = typeof(CommandWidget),
                PermissionSet = SecurityConstants.Sets.General.SetName,
                ActionName = SecurityConstants.Sets.General.Create
            ;
            masterViewToolbarSection.Items.Add(createCustomModuleWidget);
  
           // do the same for delete
           // masterViewToolbarSection.Items.Add(deleteCustomModuleWidget);
  
            
           CustomModuleGridView.ToolbarConfig.Sections.Add(masterViewToolbarSection);
  
            #endregion
  
         
  
            var translationsContextBarSection = new LocalizationWidgetBarSectionElement(CustomModuleGridView.ContextBarConfig.Sections)
            
                WrapperTagKey = HtmlTextWriterTag.Div,
                CssClass = "sfContextWidgetWrp",
                MinLanguagesCountTreshold = CustomModuleDefinitionHelper.LanguageItemsPerRow
            ;           
  
            translationsContextBarSection.Items.Add(new CommandWidgetElement(translationsContextBarSection.Items)
            
                Name = "ShowMoreTranslations",
                CommandName = CustomModuleDefinitionHelper.ShowMoreTranslationsCommandName,
                ButtonType = CommandButtonType.SimpleLinkButton,
                Text = "ShowAllTranslations",
                ResourceClassId = typeof(LocalizationResources).Name,
                WidgetType = typeof(CommandWidget),
                IsSeparator = false,
                CssClass = "sfShowHideLangVersions",
                WrapperTagKey = HtmlTextWriterTag.Div
            );
  
            translationsContextBarSection.Items.Add(new CommandWidgetElement(translationsContextBarSection.Items)
            
                Name = "HideMoreTranslations",
                CommandName = CustomModuleDefinitionHelper.HideMoreTranslationsCommandName,
                ButtonType = CommandButtonType.SimpleLinkButton,
                Text = "ShowBasicTranslationsOnly",
                ResourceClassId = typeof(LocalizationResources).Name,
                WidgetType = typeof(CommandWidget),
                IsSeparator = false,
                CssClass = "sfDisplayNone sfShowHideLangVersions",
                WrapperTagKey = HtmlTextWriterTag.Div
            );
  
            CustomModuleGridView.ContextBarConfig.Sections.Add(translationsContextBarSection);
  
            #endregion
  
            #region Grid View Mode
  
            var gridMode = new GridViewModeElement(CustomModuleGridView.ViewModesConfig)
            
                Name = "Grid"
            ;
            CustomModuleGridView.ViewModesConfig.Add(gridMode);
  
            DataColumnElement titleColumn = new DataColumnElement(gridMode.ColumnsConfig)
            
                // this will bind the title automatically
                Name = "Title",
                HeaderText = Res.Get<Labels>().Title,
                ClientTemplate = @"<a sys:href='javascript:void(0);' sys:class="" 'sf_binderCommand_edit sfItemTitle sf' + UIStatus.toLowerCase()"">
                    <strong>Title</strong>
                    <span class='sfStatusLocation'>LifecycleStatus.Message</span></a>"
            ;
            gridMode.ColumnsConfig.Add(titleColumn);
  
           
            CustomModuleDefinitionHelper.FillActionMenuItems(actionsColumn.MenuItems, actionsColumn, typeof(CustomModule).Name);
            gridMode.ColumnsConfig.Add(actionsColumn);
  
            DataColumnElement authorColumn = new DataColumnElement(gridMode.ColumnsConfig)
            
                Name = "Author",
                HeaderText = Res.Get<Labels>().Author,
                ClientTemplate = "<span>Author</span>",
                HeaderCssClass = "sfRegular",
                ItemCssClass = "sfRegular"
            ;
            gridMode.ColumnsConfig.Add(authorColumn);
  
            DataColumnElement dateColumn = new DataColumnElement(gridMode.ColumnsConfig)
            
                ///.format('dd MMM, yyyy hh:mm:ss')
                Name = "Date",
                HeaderText = Res.Get<Labels>().Date,
                ClientTemplate = "<span> (DateCreated) ? DateCreated.sitefinityLocaleFormat('dd MMM, yyyy hh:mm:ss'): '-' </span>",
                HeaderCssClass = "sfDate",
                ItemCssClass = "sfDate"
            ;
            gridMode.ColumnsConfig.Add(dateColumn);
  
            #endregion
  
            #region DecisionScreens definition
  
            DecisionScreenElement dsElement = new DecisionScreenElement(CustomModuleGridView.DecisionScreensConfig)
            
                Name = "NoItemsExistScreen",
                DecisionType = DecisionType.NoItemsExist,
                MessageType = MessageType.Neutral,
                Displayed = false,
                Title = "WhatDoYouWantToDoNow",
                MessageText = "NoContentItems",
                ResourceClassId = typeof(CustomModule).Name
            ;
  
            CommandWidgetElement actionCreateNew = new CommandWidgetElement(dsElement.Actions)
            
                Name = "Create",
                ButtonType = CommandButtonType.Create,
                CommandName = CustomModuleDefinitionHelper.CreateCommandName,
                Text = "CreateItem",
                ResourceClassId = typeof(CustomModule).Name,
                CssClass = "sfCreateItem",
                PermissionSet = SecurityConstants.Sets.General.SetName,
                ActionName = SecurityConstants.Sets.General.Create
            ;
            dsElement.Actions.Add(actionCreateNew);
  
            
  
            CustomModuleGridView.DecisionScreensConfig.Add(dsElement);
  
            #endregion
  
            #region Dialogs definition
  
            var parameters = string.Concat(
                "?ControlDefinitionName=",
                CustomModuleDefinition.BackendDefinitionName,
                "&ViewName=",
                CustomModuleDefinition.BackendInsertViewName);
            DialogElement createDialogElement = CustomModuleDefinitionHelper.CreateDialogElement(
                CustomModuleGridView.DialogsConfig,
                CustomModuleDefinitionHelper.CreateCommandName,
                "ContentViewInsertDialog",
                parameters);
            CustomModuleGridView.DialogsConfig.Add(createDialogElement);
  
            parameters = string.Concat(
                "?ControlDefinitionName=",
                CustomModuleDefinition.BackendDefinitionName,
                "&ViewName=",
                CustomModuleDefinition.BackendEditViewName);
            DialogElement editDialogElement = CustomModuleDefinitionHelper.CreateDialogElement(
                CustomModuleGridView.DialogsConfig,
                CustomModuleDefinitionHelper.EditCommandName,
                "ContentViewEditDialog",
                parameters);
            CustomModuleGridView.DialogsConfig.Add(editDialogElement);
  
            parameters = string.Concat(
                "?ControlDefinitionName=",
                CustomModuleDefinition.BackendDefinitionName,
                "&ViewName=",
                CustomModuleDefinition.BackendPreviewViewName);
            DialogElement previewDialogElement = CustomModuleDefinitionHelper.CreateDialogElement(
                CustomModuleGridView.DialogsConfig,
                CustomModuleDefinitionHelper.PreviewCommandName,
                "ContentViewEditDialog",
                parameters);
            CustomModuleGridView.DialogsConfig.Add(previewDialogElement);
  
            string permissionsParams = string.Concat(
                "?moduleName=", CustomModuleDefinition.ModuleName,
                "&typeName=", typeof(MyContentItem).AssemblyQualifiedName,
                "&title=", Res.Get<CustomModule>().PermissionsForCustomModule);
            DialogElement permissionsDialogElement = CustomModuleDefinitionHelper.CreateDialogElement(
                CustomModuleGridView.DialogsConfig,
                CustomModuleDefinitionHelper.PermissionsCommandName,
                "ModulePermissionsDialog",
                permissionsParams);
            CustomModuleGridView.DialogsConfig.Add(permissionsDialogElement);
  
            string versioningParams = string.Concat(
                "?ControlDefinitionName=",
                CustomModuleDefinition.BackendDefinitionName,
                "&moduleName=", CustomModuleDefinition.ModuleName,
                "&typeName=", typeof(MyCustomItem).AssemblyQualifiedName,
                "&title=", Res.Get<CustomModule>().PermissionsForCustomModule,
                "&backLabelText=", Res.Get<CustomModule>().BackToItems,
                "&" + CustomModuleDefinition.ComparisonViewHistoryScreenQueryParameter + "=" + CustomModuleDefinition.VersionCompariosonView);
  
            DialogElement versioningDialogElement = CustomModuleDefinitionHelper.CreateDialogElement(
                CustomModuleGridView.DialogsConfig,
                CustomModuleDefinitionHelper.HistoryCommandName,
                "VersionHistoryDialog",
                versioningParams);
            CustomModuleGridView.DialogsConfig.Add(versioningDialogElement);
  
            string versioningGridParams = string.Concat(
            "?ControlDefinitionName=",
            CustomModuleDefinition.BackendDefinitionName,
            "&moduleName=", CustomModuleDefinition.ModuleName,
            "&typeName=", typeof(MyCustomItem).AssemblyQualifiedName,
            "&title=", Res.Get<CustomModule>().PermissionsForCustomModule,
            "&backLabelText=", Res.Get<CustomModule>().BackToItems,
            "&" + CustomModuleDefinition.ComparisonViewHistoryScreenQueryParameter + "=" + CustomModuleDefinition.VersionCompariosonView);
  
            DialogElement versioningGridDialogElement = CustomModuleDefinitionHelper.CreateDialogElement(
            CustomModuleGridView.DialogsConfig,
            CustomModuleDefinitionHelper.HistoryGridCommandName,
            "VersionHistoryDialog",
            versioningGridParams);
            CustomModuleGridView.DialogsConfig.Add(versioningGridDialogElement);
  
            parameters = string.Concat(
                "?ControlDefinitionName=",
                CustomModuleDefinition.BackendDefinitionName,
                "&ViewName=",
                CustomModuleDefinition.BackendVersionPreviewViewName);
            DialogElement previewVersionDialogElement = CustomModuleDefinitionHelper.CreateDialogElement(
                CustomModuleGridView.DialogsConfig,
                CustomModuleDefinitionHelper.VersionPreviewCommandName,
                "ContentViewEditDialog",
                parameters);
            CustomModuleGridView.DialogsConfig.Add(previewVersionDialogElement);
  
            #endregion
  
            #region Links definition
  
            var url = RouteHelper.ResolveUrl(
                CustomModuleDefinitionHelper.GetBaseUrl(CustomModule.CommentsPageId),
                UrlResolveOptions.Rooted | UrlResolveOptions.RemoveTrailingSlash);
            LinkElement viewComments = new LinkElement(CustomModuleGridView.LinksConfig)
            
                Name = "viewComments",
                CommandName = CustomModuleDefinitionHelper.CommentsCommandName,
                NavigateUrl = url
            ;
            CustomModuleGridView.LinksConfig.Add(viewComments);
  
            url = RouteHelper.ResolveUrl(
                CustomModuleDefinitionHelper.GetBaseUrl(SiteInitializer.AdvancedSettingsNodeId),
                UrlResolveOptions.Rooted | UrlResolveOptions.RemoveTrailingSlash);
            url += "/CustomModule";
            LinkElement viewSettings = new LinkElement(CustomModuleGridView.LinksConfig)
            
                Name = "viewSettings",
                CommandName = CustomModuleDefinitionHelper.SettingsCommandName,
                NavigateUrl = url
            ;
            CustomModuleGridView.LinksConfig.Add(viewSettings);
  
            CustomModuleDefinitionHelper.CreateNotImplementedLink(CustomModuleGridView);
  
            #endregion
  
            backendContentView.ViewsConfig.Add(CustomModuleGridView);
  
            #endregion   
  
            #region CustomModule backend details view
  
            var CustomModuleEditDetailView = new DetailFormViewElement(backendContentView.ViewsConfig)
            
                Title = "EditItem",
                ViewName = CustomModuleDefinition.BackendEditViewName,
                ViewType = typeof(DetailFormView),
                ShowSections = true,
                DisplayMode = FieldDisplayMode.Write,
                ShowTopToolbar = false,
                ResourceClassId = typeof(CustomModule).Name,
                WebServiceBaseUrl = "~/Sitefinity/Services/Content/CustomModuleItemService.svc/",
                IsToRenderTranslationView = true
            ;
  
            backendContentView.ViewsConfig.Add(CustomModuleEditDetailView);
  
            #region Versioning Comparioson Screen
            var versionComparisonView = new ComparisonViewElement(backendContentView.ViewsConfig)
            
                Title = "VersionComparison",
                ViewName = CustomModuleDefinition.VersionCompariosonView,
                ViewType = typeof(VersionComparisonView),
                DisplayMode = FieldDisplayMode.Read,
                ResourceClassId = typeof(CustomModule).Name,
            ;
  
            backendContentView.ViewsConfig.Add(versionComparisonView);
  
            versionComparisonView.Fields.Add(new ComparisonFieldElement(versionComparisonView.Fields) FieldName = "Title", Title = "lTitle", ResourceClassId = typeof(CustomModule).Name );
            versionComparisonView.Fields.Add(new ComparisonFieldElement(versionComparisonView.Fields) FieldName = "Content", Title = "lContent", ResourceClassId = typeof(CustomModule).Name );
  
  
            versionComparisonView.Fields.Add(new ComparisonFieldElement(versionComparisonView.Fields) FieldName = "Author", Title = "Author", ResourceClassId = typeof(CustomModule).Name );
            versionComparisonView.Fields.Add(new ComparisonFieldElement(versionComparisonView.Fields) FieldName = "SourceName", Title = "SourceName", ResourceClassId = typeof(CustomModule).Name );
            
  
            #endregion
  
            var CustomModuleDetailView = new DetailFormViewElement(backendContentView.ViewsConfig)
            
                Title = "CreateNewItem",
                ViewName = CustomModuleDefinition.BackendInsertViewName,
                ViewType = typeof(DetailFormView),
                ShowSections = true,
                DisplayMode = FieldDisplayMode.Write,
                ShowTopToolbar = false,
                ResourceClassId = typeof(CustomModule).Name,
                WebServiceBaseUrl = "~/Sitefinity/Services/Content/CustomModuleItemService.svc/",
                IsToRenderTranslationView = false
            ;
  
            backendContentView.ViewsConfig.Add(CustomModuleDetailView);
  
            var previewLocalization = new Dictionary<string, string>()
            
                 "ItemVersionOfClientTemplate", Res.Get<VersionResources>().ItemVersionOfClientTemplate ,
                 "PreviouslyPublished", Res.Get<VersionResources>().PreviouslyPublishedBrackets ,
                 "CannotDeleteLastPublishedVersion", Res.Get<VersionResources>().CannotDeleteLastPublishedVersion
            ;
            var previewExternalScripts = CustomModuleDefinitionHelper.GetExtenalClientScripts(
                "Telerik.Sitefinity.Versioning.Web.UI.Scripts.VersionHistoryExtender.js, Telerik.Sitefinity",
                "OnDetailViewLoaded");
            var CustomModuleHistoryPreviewDetailView = new DetailFormViewElement(backendContentView.ViewsConfig)
            
                Title = "EditItem",
                ViewName = CustomModuleDefinition.BackendVersionPreviewViewName,
                ViewType = typeof(DetailFormView),
                ShowSections = true,
                DisplayMode = FieldDisplayMode.Read,
                ShowTopToolbar = false,
                ResourceClassId = typeof(CustomModule).Name,
                ExternalClientScripts = previewExternalScripts,
                 WebServiceBaseUrl = "~/Sitefinity/Services/Content/CustomModuleItemService.svc/",
                ShowNavigation = true,
                Localization = previewLocalization
            ;
  
            backendContentView.ViewsConfig.Add(CustomModuleHistoryPreviewDetailView);
  
            var CustomModulePreviewDetailView = new DetailFormViewElement(backendContentView.ViewsConfig)
            
                Title = "EditItem",
                ViewName = CustomModuleDefinition.BackendPreviewViewName,
                ViewType = typeof(DetailFormView),
                ShowSections = true,
                DisplayMode = FieldDisplayMode.Read,
                ShowTopToolbar = false,
                ResourceClassId = typeof(CustomModule).Name,
                ExternalClientScripts = previewExternalScripts,
                ShowNavigation = true,
                WebServiceBaseUrl = "~/Sitefinity/Services/Content/CustomModuleItemService.svc/"
  
            ;
  
            backendContentView.ViewsConfig.Add(CustomModulePreviewDetailView);
  
            #region CustomModule backend forms definition
  
            #region Insert Form
            CustomModuleCustomModuleDefinition.CreateBackendSections(CustomModuleInsertDetailView);
            CustomModuleDefinitionHelper.CreateBackendFormToolbar(CustomModuleInsertDetailView, typeof(CustomModule).Name, true);
            #endregion
  
            #region Edit Form
  
            CustomModuleDefinition.CreateBackendSections(CustomModuleEditDetailView);
            CustomModuleDefinitionHelper.CreateBackendFormToolbar(CustomModuleEditDetailView, typeof(CustomModule).Name, false);
  
            #endregion
  
            #region Preview History Form
            CreateBackendSections(CustomModuleHistoryPreviewDetailView, FieldDisplayMode.Read);
            CustomModuleDefinitionHelper.CreateHistoryPreviewToolbar(CustomModuleHistoryPreviewDetailView, typeof(CustomModule).Name);
          
            #endregion
  
            #region Preview Form
            CreateBackendSections(CustomModulePreviewDetailView, FieldDisplayMode.Read);
            //TODO: add the preview screen toolbar widgets -->Edit,etc...
  
            #endregion
  
            #endregion
  
            #endregion
  
            return backendContentView;
        
  
        #endregion
  
        #region Frontend CustomModuleDefinition
  
        /// <summary>
        /// Defines the ContentView control for CustomModule on the frontend
        /// </summary>
        /// <param name="parent">The parent configuration element.</param>
        /// <returns>A configured instance of <see cref="ContentViewControlElement"/>.</returns>
        internal static ContentViewControlElement DefineCustomModuleFrontendContentView(ConfigElement parent)
        
            // define content view control
            var controlDefinition = new ContentViewControlElement(parent)
            
                ControlDefinitionName = CustomModuleDefinition.FrontendDefinitionName,
                ContentType = typeof(MyCustomItem)
            ;
  
            // *** define views ***
  
            #region CustomModule backend list view
  
            var CustomModuleListView = new ContentViewMasterElement(controlDefinition.ViewsConfig)
            
                ViewName = CustomModuleDefinition.FrontendListViewName,
                ViewType = typeof(MasterListView),
                AllowPaging = true,
                DisplayMode = FieldDisplayMode.Read,
                ItemsPerPage = 20,
                ResourceClassId = typeof(CustomModule).Name,
                FilterExpression = CustomModuleDefinitionHelper.PublishedOrScheduledFilterExpression,
                SortExpression = "PublicationDate DESC"
            ;
  
            controlDefinition.ViewsConfig.Add(CustomModuleListView);
  
            #endregion
  
            #region CustomModule backend details view
  
            var CustomModuleDetailsView = new ContentViewDetailElement(controlDefinition.ViewsConfig)
            
                ViewName = CustomModuleDefinition.FrontendDetailViewName,
                ViewType = typeof(DetailsSimpleView),
                ShowSections = false,
                DisplayMode = FieldDisplayMode.Read,
                ResourceClassId = typeof(CustomModule).Name
            ;
  
            controlDefinition.ViewsConfig.Add(CustomModuleDetailsView);
  
            #endregion
  
            return controlDefinition;
        
  
        #endregion
  
        #region Helper methods
  
        private static void CreateBackendSections(DetailFormViewElement detailView)
        
            CreateBackendSections(detailView, FieldDisplayMode.Write);
        
  
        /// <summary>
        /// Creates the backend sections.
        /// </summary>
        private static void CreateBackendSections(DetailFormViewElement detailView, FieldDisplayMode displayMode)
        
            #region Version Section
            if (displayMode == FieldDisplayMode.Read)
            
                var versionSection = new ContentViewSectionElement(detailView.Sections)
                
                    Name = "Sidebar",
                    CssClass = "sfItemReadOnlyInfo"
                ;
  
                var versionField = new VersionNoteControlDefinitionElement(versionSection.Fields)
                
  
                    Title = Res.Get<CustomModule>().lTitle,
                    ResourceClassId = typeof(CustomModule).Name,
                    FieldName = "Comment",
                    WrapperTag = HtmlTextWriterTag.Li,
                    DisplayMode = displayMode
  
                ;
                versionSection.Fields.Add(versionField);
                detailView.Sections.Add(versionSection);
            
            #endregion
  
            #region Toolbar section
  
            if (detailView.ViewName == CustomModuleDefinition.BackendEditViewName)
            
                var toolbarSection = new ContentViewSectionElement(detailView.Sections)
                
                    Name = CustomModuleDefinitionHelper.ToolbarSectionName
                ;
  
                var languageListFieldElement = new LanguageListFieldElement(toolbarSection.Fields)
                
                    ID = "languageListField",
                    FieldType = typeof(LanguageListField),
                    ResourceClassId = typeof(CustomModule).Name,
                    Title = Res.Get<CustomModule>().Language,
                    DisplayMode = displayMode,
                    FieldName = "languageListField",
                    DataFieldName = "AvailableLanguages"
                ;
                toolbarSection.Fields.Add(languageListFieldElement);
  
                detailView.Sections.Add(toolbarSection);
            
  
            #endregion
  
            #region Main section
  
            var mainSection = new ContentViewSectionElement(detailView.Sections)
            
                Name = "MainSection",
  
            ;
  
            var titleField = new TextFieldDefinitionElement(mainSection.Fields)
            
                ID = "titleFieldControl",
                DataFieldName = "Title",
                DisplayMode = displayMode,
                Title = Res.Get<CustomModuleResources>().lTitle,
                CssClass = "sfTitleField",
                ResourceClassId = typeof(CustomModuleResources).Name,
                WrapperTag = HtmlTextWriterTag.Li,
            ;
            
            mainSection.Fields.Add(titleField);
  
            #endregion
  
           
  
  
            #region Status
  
            CustomModuleDefinitionHelper.AddStatusFieldSectionDefinition(detailView, typeof(CustomModuleResources).Name, displayMode);
            #endregion
        
  
        #endregion
  
        #region Constants
  
           // define all public or static constraints here
        #endregion
    


All the best,
Ivan Dimitrov
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 05-Nov-2010 00:00

Hello, I will try the field control snippet.


But what I would prefer is a way to simply add/update/delete record record the dynamic type I created. To be more specific, let's say I created following type:

App.WorkWith().DynamicData().Type()
    .CreateNew("ExchangeRecord", "MyModule")
    .Field().TryCreateNew("Title", typeof (string), ref changedDb).Done()
    .Field().TryCreateNew("Content", typeof (string), ref changedDb).Done()
    .Field().TryCreateNew("CreatedBy", typeof(Guid), ref changedDb).Done()
    .Field().TryCreateNew("CreatedOn", typeof(DateTimeOffset), ref changedDb).SaveChanges(true));

Now, I need to insert a new row into the database, what API do I call? I want to get all ExchangeRecord entries from the database, what API do I call?

I hope this clarifies my question better.

Posted by Community Admin on 07-Nov-2010 00:00

Hello Bill,

You can reuse the FieldControlsBinder and set your custom web service that will get, save,  sort etc your data.

Another option is working with the Telerik.Sitefinity.Web.Scripts.ClientManager.js and its public methods like

  • InvokePut
  • InvokeDelete
sample

    RemoveDynamicItemData: function (ver)
    // get the client manager
    var clientManager = this.get_manager();
    // url to your custom service where you have method for deleting
    var serviceUrl = this._serviceBaseUrl;
    var urlParams = [];
    // provider name that your module will use
    if (this._providerName != null)
        urlParams['provider'] = this._providerName;
    
 
    var keys = [];
    // get data item ids
    if (this._dataItem != null)
        keys.push(this._dataItem.Id);
    
   
    clientManager.InvokeDelete(serviceUrl, urlParams, keys, this._deleteSuccess, this._deleteFailure, this);
 
 
 // write call back functions.


Greetings,
Ivan Dimitrov
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 08-Nov-2010 00:00

"You can reuse the FieldControlsBinder and set your custom web service that will get, save,  sort etc your data."


Now, how do I create a custom web service? Are you talking about creating my own database table (as opposed to using Sitefinity Dynamic Type) and create a standard .NET database reading service?

Edit: to be more specific, I'd like to know where is the API methods that I can provide it with a type name (used when creating the Dynamic Type), and it'll give me back a list of objects of that type from the database?

Posted by Community Admin on 08-Nov-2010 00:00

Hello Bill,

You can create a service that inherits from ContentService or reuse one of the built-in services. You do not need a custom database table when you work with dynamic data. You can take a look at Client Side programming

Regards,
Ivan Dimitrov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 08-Nov-2010 00:00

Thanks for the pointers to client side programming, I have a better understanding of Sitefinity architecture now. So I will need to bind client side control (using various ways you have described) to a WCF service which handles the CRUD operations of the object.

That leads back to my original question, some where in this WCF service, it needs to actually work with the data. i.e. getting all ExchangeRecord in my previous example. Now, how do I get all the ExchangeRecord inside this WCF service?

Posted by Community Admin on 09-Nov-2010 00:00

Hello Bill,

First, it depends on whether "ExchangeRecord" inherits from "Telerik.Sitefinity.GenericContent.Model.Content" and whether you will work with asynchronous calls. If you want to work on the server side you can see the implementation of JobsModule in the SDK

To work with asynchronous calls you should create a definition class as shown in the previous posts and use DetailFormViewElement where the ViewType is DetailFormView. In this case this allows you to use FieldControlsBinder control that will take care of the client requests.

var EditDetailView = new DetailFormViewElement(backendContentView.ViewsConfig)
          
              Title = "EditItem",
              ViewName = "BackendEditViewName,
              ViewType = typeof(DetailFormView),
              ShowSections = true,
              DisplayMode = FieldDisplayMode.Write,
              ShowTopToolbar = false,
              ResourceClassId = typeof(ModuleResources).Name,
              WebServiceBaseUrl = "~/Sitefinity/Services/Content/CustomItemService.svc/",
              IsToRenderTranslationView = false
          ;

Your service could implement the methods of ContentServiceBase


sample

namespace Telerik.Sitefinity.Modules.Samples.Web.Services
     
    public class CustomItemService : ContentServiceBase<MyCustomItem, MyCustomItemViewModel, MyManager>
    
       
        public override IQueryable<MyCustomItem> GetContentItems(string providerName)
        
            return this.GetManager(providerName).GetNItems();
        
 
       
        public override IQueryable<MyCustomItem> GetChildContentItems(Guid parentId, string providerName)
        
           //
        
 
        
        public override MyCustomItem GetContentItem(Guid id, string providerName)
                  
            try
            
                return this.GetManager(providerName).GetItem(id);
            
            catch (Exception error)
            
               // not found
            
        
 
       
        public override MyManager GetManager(string providerName)
                   
            return MyManager.GetManager(providerName, WcfContext.CurrentTransactionName);
        
 
        public override IEnumerable<MyCustomItemViewModel> GetViewModelList(IEnumerable<MyCustomItem> contentList, GenericContent.ContentDataProviderBase dataProvider)
        
            var viewModelList = new List<MyCustomItemViewModel>();
            foreach (var item in contentList)
                viewModelList.Add(new MyCustomItemViewModel(item, dataProvider));
            return viewModelList;
        
    

In the service you should have view model class for the "MyItem" model.

Manually you can use
  • InvokeGet
  • InvokeDelete
  • InvokePost
  • InvokePut
methods of the ClientManager.

Regards,
Ivan Dimitrov
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 26-Nov-2010 00:00

Hi Ivan, you just pushed the question further, basically, your code shows that this MyManager class will handle the CRUD operations. But how?


To make things easier. since you're posting all this snippets, I'm sure you have a working custom module sample that uses dynamic type. Is it possible to give me that so I can see the full picture?

Thanks,
Bill

Posted by Community Admin on 29-Nov-2010 00:00

Hello Bill,

"MyManager" can handle CRUD operations if you have a DataProvider that inherits from ContentDataProviderBase
 for it and We are working on a sample but most of its code is posted here.

All the best,
Ivan Dimitrov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 29-Nov-2010 00:00

I don't understand, why can't the CRUD operations be simply some code like this?

var record = new Dictionary<string, object>();
record.Add("FieldName1", FieldValue1);
record.Add("FieldName2", FieldValue2);
record.Add("FieldName3", FieldValue3);
App.WorkWith().DynamicData().CreateNew("MyCustomType", record);

Posted by Community Admin on 11-Dec-2010 00:00

Hello Bill Y,

I sent you some examples that show how to perform these operations in this post.

Kind regards,
Ivan Dimitrov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 13-Dec-2010 00:00

Hi Ivan,

Could you please provide a sample working source code of this module?

Thanks,
Duneel

Posted by Community Admin on 13-Dec-2010 00:00

Hi Duneel,

Could you tell me which module you are referring to?

All the best,
Ivan Dimitrov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 13-Dec-2010 00:00

Hi Ivan,

Really sorry for the confusion. I was referring to the code you have provided in your post posted on Nov 5, 2010. I want to implement a basic custom module (let's say a contact list, with few text fields) with all the backend views like Create New View, Edit View, List View, Preview View and Version Preview.

I am actually new to custom module development and I'm not sure whether this post is actually a good starting point. I followed the sample job module too.

Thanks!
Duneel

Posted by Community Admin on 14-Dec-2010 00:00

Hello Duneel,

We are working an a sample module that will be available with the official release. For the official release you will be able to add custom fields to the content modules directly from the UI, so you do not have to write any code if you want to extend one of the built-in content types with a field.

Best wishes,
Ivan Dimitrov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 15-Dec-2010 00:00

Is adding meta data from the UI available in the RC now? I tried looking thru the docs and the administration section of SF, but could not find how to do this.

Posted by Community Admin on 15-Dec-2010 00:00

Hello bemara57,

It is a new feature and it is not included in the RC release. We will have a a build next week where we will include some new functionality, so you will be able to create custom content types.

Best wishes,
Ivan Dimitrov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 09-Jan-2011 00:00

Can anyone provide a small sample of what is discussed above?

Posted by Community Admin on 19-Jan-2011 00:00

Hi Bill Y,

I recently explained how to work with dynamic types on the forums.

As far as modules goes, there should be a 'Products' module that comes with the SDK. Take a look, as it is maintained and works. You might want to use it as a starting point when developing new modules.

Greetings,
Dido
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 19-Jan-2011 00:00

Thanks Dido for the description. But I was asking about a demonstration of the code Ivan pasted over here ("CustomModuleCustomModuleDefinition" class) for backend controls (decision panels, toolbars etc).

And yeah, your reply helped me a lot too in other aspects.

Posted by Community Admin on 19-Jan-2011 00:00

Hello saadi,

CustomModuleCustomModuleDefinition is the name of the sample class used above for creating custom definition. You can see how to create a definition class for your module in our Products sample module for Sitefinity 4.0 included in the SDK.

Regards,
Ivan Dimitrov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 20-Jan-2011 00:00

Yes, that is what I am asking for. I just wanted a sample of custom definition so that I could see how to create definition classes for every module.
Or, if there is any module in 4.0 that already exhibits same then please let me know.

Posted by Community Admin on 20-Jan-2011 00:00

Hello saadi,

Please check the Products sample module included in our SDK.

Regards,
Ivan Dimitrov
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items

Posted by Community Admin on 20-Jan-2011 00:00

But that isnt for Sitefinity 3.x? Ahh I cant find any way

This thread is closed