+1-888-365-2779
Try Now
More in this section

Forums / General Discussions / Creating Dynamic Type

Creating Dynamic Type

25 posts, 0 answered
  1. Bill Y
    Bill Y avatar
    22 posts
    Registered:
    04 Nov 2010
    05 Nov 2010
    Link to this post
    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
  2. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    05 Nov 2010
    Link to this post
    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
  3. Bill Y
    Bill Y avatar
    22 posts
    Registered:
    04 Nov 2010
    05 Nov 2010
    Link to this post
    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.
  4. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    07 Nov 2010
    Link to this post
    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
  5. Bill Y
    Bill Y avatar
    22 posts
    Registered:
    04 Nov 2010
    08 Nov 2010
    Link to this post
    "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?
  6. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    08 Nov 2010
    Link to this post
    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
  7. Bill Y
    Bill Y avatar
    22 posts
    Registered:
    04 Nov 2010
    08 Nov 2010
    Link to this post
    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?
  8. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    09 Nov 2010
    Link to this post
    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
  9. Bill Y
    Bill Y avatar
    22 posts
    Registered:
    04 Nov 2010
    26 Nov 2010
    Link to this post
    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
  10. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    29 Nov 2010
    Link to this post
    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
  11. Bill Y
    Bill Y avatar
    22 posts
    Registered:
    04 Nov 2010
    29 Nov 2010
    Link to this post
    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);

  12. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    11 Dec 2010
    Link to this post
    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
  13. Duneel
    Duneel avatar
    166 posts
    Registered:
    08 Dec 2010
    13 Dec 2010
    Link to this post
    Hi Ivan,

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

    Thanks,
    Duneel
  14. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    13 Dec 2010
    Link to this post
    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
  15. Duneel
    Duneel avatar
    166 posts
    Registered:
    08 Dec 2010
    13 Dec 2010
    Link to this post
    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
  16. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    14 Dec 2010
    Link to this post
    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
  17. bemara57
    bemara57 avatar
    135 posts
    Registered:
    27 Mar 2008
    15 Dec 2010
    Link to this post
    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.
  18. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    15 Dec 2010
    Link to this post
    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
  19. Saad
    Saad avatar
    98 posts
    Registered:
    10 Oct 2008
    09 Jan 2011
    Link to this post
    Can anyone provide a small sample of what is discussed above?
  20. Dido
    Dido avatar
    149 posts
    Registered:
    24 Sep 2012
    19 Jan 2011
    Link to this post
    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
  21. Saad
    Saad avatar
    98 posts
    Registered:
    10 Oct 2008
    19 Jan 2011
    Link to this post
    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.
  22. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    19 Jan 2011
    Link to this post
    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
  23. Saad
    Saad avatar
    98 posts
    Registered:
    10 Oct 2008
    20 Jan 2011
    Link to this post
    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.
  24. Ivan Dimitrov
    Ivan Dimitrov avatar
    16072 posts
    Registered:
    25 Nov 2016
    20 Jan 2011
    Link to this post
    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
  25. Saad
    Saad avatar
    98 posts
    Registered:
    10 Oct 2008
    20 Jan 2011
    Link to this post
    But that isnt for Sitefinity 3.x? Ahh I cant find any way
25 posts, 0 answered