More in this section
Categories
Bloggers
Blogs RSS feed

Creating Dynamic Module Items Using the Module Builder API

by Josh Morales

We previously looked at how you can retrieve dynamic module items using the Module Builder API. Today we'll take a look at how you can use that same API to also create new items.

Using the sample code from the Code Reference (generated for every dynamic module you create) you can easily develop a new public widget that allows your site visitors to create items. Because dynamic module items support the Content Lifecycle, you can prevent these items from being published before they are reviewed.

For this example, we will once again be using the Showcases module example that Gabe created and has available on the Module Builder Webinar notes.

Submit Showcases Widget

Because Sitefinity widgets are simply user controls, all we really need to do is create a new User Control and add our input markup plus the backing code to write that data to the API. Start with the frontend of the User Control:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="SubmitShowcase.ascx.cs" Inherits="SitefinityWebApp.Modules.Showcases.SubmitShowcase" %><%@ Register Assembly="Telerik.Sitefinity" Namespace="Telerik.Sitefinity.Web.UI.Fields" TagPrefix="sf" %><div class="sfShowcaseSubmitForm"> <p>Do you have a website you would like us to feature? Submit it below!</p> <div> <label for="Title" class="txtLbl">Company or Website Name</label> <asp:TextBox ID="Title" ClientIDMode="Static" runat="server" /> </div> <div> <label for="SiteUrl" class="txtLbl">Site Url</label> <asp:TextBox ID="SiteUrl" ClientIDMode="Static" runat="server" /> </div> <div> <label for="LaunchDate" class="txtLbl">Launch Date</label> <telerik:RadDatePicker ID="LaunchDate" runat="server" ClientIDMode="Static" /> <div> <label for="Industries" class="txtLbl">Industry</label> <asp:DropDownList ID="Industries" ClientIDMode="Static" runat="server" /> </div> <div> <label class="txtLbl">Case Study Features</label> <asp:CheckBoxList ID="FeaturesList" ClientIDMode="Static" runat="server" RepeatColumns="4" RepeatDirection="Horizontal" RepeatLayout="Table" /> </div> <div> <label for="Countries" class="txtLbl">Country</label> <asp:DropDownList ID="Countries" ClientIDMode="Static" runat="server" /> </div> <div> <label>Sitefinity Version</label> <asp:RadioButtonList ID="Version" runat="server"> <asp:ListItem Text="Sitefinity 3.x" Value="Sitefinity 3.x" /> <asp:ListItem Text="Sitefinity 4.x" Value="Sitefinity 4.x" /> </asp:RadioButtonList> </div> <div> <label for="Thumbnail" class="txtLbl">Website Screenshot</label> <telerik:RadUpload ID="Thumbnail" ClientIDMode="Static" runat="server" AllowedFileExtensions=".gif,.jpg,.jpeg,.png" MaxFileInputsCount="1" InputSize="45" ControlObjectsVisibility="None" /> <div> <label for="CaseStudy" class="txtLbl">Case Study (PDF)</label> <telerik:RadUpload ID="CaseStudy" ClientIDMode="Static" runat="server" AllowedFileExtensions=".pdf" MaxFileInputsCount="1" InputSize="45" ControlObjectsVisibility="None" /> <div> <label for="Content" class="txtLbl">Case Study</label> <sf:FormManager ID="formManager" runat="server" /> <sf:HtmlField ID="Content" ClientIDMode="Static" runat="server" Width="99%" Height="370px" DisplayMode="Write" FixCursorIssue="True" /> </div> <div> <asp:Button ID="btnSubmit" runat="server" Text="Submit" OnClick="Submit" /> </div> <telerik:RadInputManager ID="RadInput" runat="server"> <telerik:RegExpTextBoxSetting ValidationExpression="http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&amp;=]*)?" ClearValueOnError="false"> <TargetControls> <telerik:TargetInput ControlID="SiteUrl" /> </TargetControls> </telerik:RegExpTextBoxSetting> <telerik:TextBoxSetting Validation-IsRequired="true"> <TargetControls> <telerik:TargetInput ControlID="Title" /> <telerik:TargetInput ControlID="SiteUrl" /> <telerik:TargetInput ControlID="LaunchDate" /> <telerik:TargetInput ControlID="Content" /> </TargetControls> </telerik:TextBoxSetting> </telerik:RadInputManager> </div> </div> </div></div>

This is simply a collection of input controls to collect the data from the user that corresponds to the fields for our dynamic content type. For simplicity, we've excluded validation controls.

Choice Fields

In the current version of Sitefinity (4.4 as of today), choice fields used by the module do not yet persist the valid list of items anywhere other than on the backend sitefinity forms that are created by the module. As a result, it is not yet possible to automatically bind input controls such as dropdown menus and radio buttons to those choices, but instead must be manually populated.

This is what we have done in the code above for the Sitefinity Version field, and explicitly defined the valid choices for our module.

Future versions of the module builder will address this so that you can access these choices and bind to them automatically.

Code-Behind: On Control Load

Although we cannot bind to choice fields automatically, there are some controls we can load automatically using the regular Sitefinity API. Specifically we can pre-load the Taxonomy fields for Industry, Features, and Countries.

For this I've defined a helper method that will retrieve the list taxon items for a taxonomy based on the name of the parent taxonomy title.

private IEnumerable<ITaxon> GetTaxonomy<TTaxonomy>(string TaxonomyName) where TTaxonomy : class, ITaxonomy{
    // bind categories selector var taxMgr = TaxonomyManager.GetManager();
    var taxonomy = taxMgr.GetTaxonomies<TTaxonomy>().Where(t => t.Title == TaxonomyName).FirstOrDefault();
    if (taxonomy == null) return null;

    // return taxa items var taxa = taxonomy.Taxa;
    return taxa;
}

Now we can simply call that helper method on the Page_Load event so that our taxonomy controls are loaded and bound.

protected void Page_Load(object sender, EventArgs e)
{
    if (IsPostBack) return;

    // bind Industries menu foreach (var industry in GetTaxonomy<HierarchicalTaxonomy>("Industries"))
    {
        var item = new ListItem(industry.Title, industry.Id.ToString());
        Industries.Items.Add(item);
    }

    // bind features selectors foreach (var feature in GetTaxonomy<FlatTaxonomy>("Features"))
    {
        var chk = new ListItem(feature.Title, feature.Id.ToString());
        FeaturesList.Items.Add(chk);
    }

    // bind countries selectors foreach (var country in GetTaxonomy<FlatTaxonomy>("Countries"))
    {
        var item = new ListItem(country.Title, country.Id.ToString());
        Countries.Items.Add(item);
    }
}

Code-Behind: On Submit

Once the user completes the form and submits it, we want to save that data into a new dynamic module item. Because we have media fields in our content model, we need to first support uploading of media to the Sitefinity Images and Documents modules. This is done with helper methods of each type that write the file contained in a RadUpload control to the database.

protected Telerik.Sitefinity.Libraries.Model.Image UploadImage(RadUpload radUploader, string title)
{
    Telerik.Sitefinity.Libraries.Model.Image img = null;
    if (radUploader.UploadedFiles.Count == 0) return img;

    // select showcases album var imgMgr = LibrariesManager.GetManager();
    var album = imgMgr.GetAlbums().Where(a => a.Title == "Showcase Screenshots").FirstOrDefault();
    
    // prepare transaction using (var sf = App.Prepare().SetTransactionName("UploadTransaction").WorkWith())
    {
        // temporarily disable security checks to allow image creation without login sf.Images().GetManager().Provider.SuppressSecurityChecks = true;

        // save image properties img = imgMgr.CreateImage();
        img.Parent = album;
        img.Title = title;
        img.UrlName = title + "_Screenshot";
        img.Status = Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Master;

        // upload Image var file = radUploader.UploadedFiles[0];
        imgMgr.Upload(img, file.InputStream, file.GetExtension());
        imgMgr.Publish(img);
        imgMgr.SaveChanges();

        // re-enable security sf.Images().GetManager().Provider.SuppressSecurityChecks = false;
    }

    // return image so it can be associated with module content item return img;
}

protected Telerik.Sitefinity.Libraries.Model.Document UploadDocument(RadUpload radUploader, string title)
{
    Telerik.Sitefinity.Libraries.Model.Document doc = null;
    if (CaseStudy.UploadedFiles.Count == 0) return doc;

    // select showcases album var docMgr = LibrariesManager.GetManager();
    var album = docMgr.GetDocumentLibraries().Where(a => a.Title == "Showcase Case Studies").FirstOrDefault();

    // prepare transaction using (var sf = App.Prepare().SetTransactionName("UploadTransaction").WorkWith())
    {
        // temporarily disable security checks to allow image creation without login sf.Documents().GetManager().Provider.SuppressSecurityChecks = true;

        // save image properties doc = docMgr.CreateDocument();
        doc.Parent = album;
        doc.Title = title;
        doc.UrlName = title;
        doc.Status = Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Master;

        // upload Image var file = radUploader.UploadedFiles[0];
        docMgr.Upload(doc, file.InputStream, file.GetExtension());
        docMgr.Publish(doc);
        docMgr.SaveChanges();

        // re-enable security sf.Documents().GetManager().Provider.SuppressSecurityChecks = false;
    }

    // return image so it can be associated with module content item return doc;
}

Finally, we simply go through each field and map the simple properties (text, datetime, boolean, etc) using the SetValue() extension method.

NOTE: be sure to include the using Telerik.Sitefinity.Model namespace to use this extension method.

public void Submit(object sender, EventArgs e)
{
    // initialize the dynamic module content manager DynamicModuleManager mgr = DynamicModuleManager.GetManager();
    

    // initialize a new [ModuleItem] Type showcaseType = TypeResolutionService.ResolveType("Telerik.Sitefinity.DynamicTypes.Model.Showcases.Showcase");
    DynamicContent showcaseItem = mgr.CreateDataItem(showcaseType);

    // save simple fields to the item var title = Title.Text.Trim();
    showcaseItem.SetValue("Title", title);
    showcaseItem.SetValue("SiteUrl", SiteUrl.Text);    
    showcaseItem.SetValue("LaunchDate", LaunchDate.SelectedDate);
    showcaseItem.SetValue("UrlName", new Lstring(title.Replace(" ", "-"))); // TODO: use regex to strip characters showcaseItem.SetValue("Content", Content.Value.ToString());
    showcaseItem.SetValue("Platform", new string[] { Version.SelectedValue });

    // save selected country showcaseItem.Organizer.AddTaxa("countries", new Guid(Countries.SelectedValue));

    // save selected category showcaseItem.Organizer.AddTaxa("industries", new Guid(Industries.SelectedValue));

    // save selected tags foreach (ListItem tag in FeaturesList.Items)
        if (tag.Selected) showcaseItem.Organizer.AddTaxa("features", new Guid(tag.Value));

    // save thumbnail if present var img = UploadImage(Thumbnail, title);
    if (img != null)
    {
        var contentLink = new ContentLink(img.Parent.Id, img.Id);
        var screenshots = new List<ContentLink>() { contentLink };
        showcaseItem.SetValue("Screenshot", screenshots.ToArray());
    }

    // save document if present var doc = UploadDocument(CaseStudy, title);
    if (doc != null)
    {
        var contentLink = new ContentLink(doc.Parent.Id, doc.Id);
        var screenshots = new List<ContentLink>() { contentLink };
        showcaseItem.SetValue("CaseStudy", screenshots.ToArray());
    }

    // You need to call SaveChanges() in order for the items to be actually persisted to data store showcaseItem.SetValue("Owner", SecurityManager.GetCurrentUserId());
    showcaseItem.SetValue("PublicationDate", DateTime.Now);
    
    // uncomment this line to publish the item instead of saving as draft //mgr.Lifecycle.Publish(showcaseItem); mgr.SaveChanges();
    
    //// TODO: enable workflow //var contextBag = new Dictionary<string, string>(); //contextBag.Add("ContentType", showcaseType.FullName); //WorkflowManager.MessageWorkflow( // showcaseItem.Id, // showcaseType, // null, // "SendForApproval", // false, // contextBag);}

By default, items created will remain in Draft status. To publish an item, simply uncomment the line in the code above the SaveChanges() method.

mgr.Lifecycle.Publish(showcaseItem);

Wrapping Up

With just a few lines of code on a single user control, we were able to quickly extend our module to allow public users to add content items. The Code Reference is full of additional helpful examples to help you customize and make the most of your new dynamic modules.

If you haven't already, take some time to try out the new Module Builder, and as always, be sure to share your experiences with us in the Sitefinity Discussion Forums.

31 comments

Leave a comment
  1. ian Jun 14, 2012
    Hi

    For simplicity, you've excluded validation controls, but if you were to include them how would you do this? Are they normal ASP.NET validation controls or can you link back to your module items to reference the data type etc?

    Thanks        
  2. ian Jun 14, 2012
    Hi

    For simplicity, you've excluded validation controls, but if you were to include them how would you do this? Are they normal ASP.NET validation controls or can you link back to your module items to reference the data type etc?

    Thanks        
  3. Josh Jun 20, 2012
    Because this is a simple user control (ascx) you could certainly use the normal asp.net validation controls (or the Telerik RadInput control) to validate input.

    You can also validate again on the server side with custom logic inside the Submit method. It's entirely up to you!
  4. kostum badut maskot Apr 04, 2018
    I  real   glad  to find this  web site  on bing, just what I was  searching  for : D  likewise   saved to bookmarks . kostum badut maskot
  5. comfortable bed sheets Apr 05, 2018
    You can easily set aside a lot of directed adventures with assorted car experts. Various deal great delivers several might take your corporation for a tour to a market location, or perhaps for a trip to new york. ?????? ??? comfortable bed sheets
  6. karnataka puc results 2018 Apr 05, 2018
    Didn’t the pagans come up with some way too cool holidays? karnataka puc results 2018
  7. voyance-amour-eternel.com Apr 06, 2018
    I like this post, enjoyed this one  appreciate it for  putting up. voyance-amour-eternel.com
  8. 7ff  Apr 06, 2018
    There are various agencies which deals with evidences located at a crime scene. Police use it for investigation, prosecuting attorney presents it before court of law as well as a forensic science technician analyzes evidences thoroughly to help other agencies in criminal procedure. A forensic science technician conducts comprehensive chemical and physical study of evidence submitted by a law enforcement agency 7ff 
  9. best company to buy gifts Apr 07, 2018
    Were required to give you that almost no remark in order to thanks a lot yet again of these spectacular techniques you might have provided in this posting. It’s so particularly generous with folks such as you to generate unreservedly what the majority of us might have marketed for an book to earn some dough in their own business, primarily since you may have tried it in the event you wanted. The tactics also acted to be good way to know that everyone’s similar desire just as my own, personal to figure out completely more regarding this condition. I’m sure there are thousands of more pleasant opportunities up front for many who go through your website post. best company to buy gifts
  10. eternity rings Apr 07, 2018
    Sites we Like…… [...] Every once in a while we choose blogs that we read. Listed below are the latest sites that we choose [...]…… eternity rings
  11. Kiyason Ziyily Formula Apr 07, 2018
    I’m impressed, I must say. Actually rarely must i encounter a weblog that’s both educative and entertaining, and let me tell you, you may have hit the nail for the head. Your notion is outstanding; the pain is something that not enough individuals are speaking intelligently about. My business is happy we found this at my seek out something regarding this. Kiyason Ziyily Formula
  12. aadil Apr 07, 2018
    PUC Result 2018 - Karnataka Secondary Education Examination Board 12th Results on http://kar.boardresult-nic.in/
  13. tìm người yêu lâu dài Apr 10, 2018
    There are some attention-grabbing closing dates on this article however I don’t know if I see all of them middle to heart. There is some validity but I’ll take hold opinion until I look into it further. Good article , thanks and we want more! Added to FeedBurner as nicely tìm người yêu lâu dài
  14. Camping Apr 10, 2018
    Then after a really long time, a decade perhaps, you can become a captain. Camping
  15. stealth commissions bonuses Apr 10, 2018
    Just want to say your article is as surprising. The clearness in your post is simply nice and i can assume you are an expert on this subject. Fine with your permission let me to grab your RSS feed to keep updated with forthcoming post. Thanks a million and please carry on the enjoyable work. stealth commissions bonuses
  16. Lucht/water warmtepompen Apr 12, 2018
    Yay google is my  world beater  assisted  me to find this great   site! . Lucht/water warmtepompen
  17. aadil Apr 14, 2018
    check rbse 10th and rajsthan board 12th class result at - http://rbse.boardresult-nic.in/
  18. aadil Apr 16, 2018
    check the haryan board complete latest information and news update about - <a href="http://hbse.boardresult-nic.in/">hbse result 2018</a>
  19. aail Apr 16, 2018
    1. check the haryan board complete latest information and news update about - hbse result 2018
  20. asd Apr 17, 2018
    I tend to some what disagree with what you said but in hindsight I don’t follow the subject very well. You might have a much better grasp than me. bovegas
  21. asd Apr 17, 2018
    we are always looking for alternative or green energy because we want to stop polluting the environment.. golden lion
  22. asd Apr 17, 2018
    I am typically to blogging i truly appreciate your site content. This great article has truly peaks my interest. Let me bookmark your web blog and keep checking for brand spanking new info. bet3000
  23. das Apr 17, 2018
    if you want a great wedding decoration, just fill them up with lots of flowers and laces` casumo
  24. zxc Apr 18, 2018
    I like this post,And I guess that they having fun to read this post,they shall take a good site to make a information,thanks for sharing it to me. bonus codes
  25. qw Apr 18, 2018
    This is a great inspiring article.I am pretty much pleased with your good work.You put really very helpful information... no deposit freespins
  26. fad Apr 18, 2018
    Thanks for the valuable information and insights you have so provided here... freespins
  27. sdf Apr 18, 2018
    You know your projects stand out of the herd. There is something special about them. It seems to me all of them are really brilliant! casino freespins
  28. sdf Apr 18, 2018
    Its a great pleasure reading your post.Its full of information I am looking for and I love to post a comment that "The content of your post is awesome" Great work. blog
  29. zxc Apr 18, 2018
    Love what you're doing here guys, keep it up you also go here: mybet casino
  30. sda Apr 21, 2018
    What is the chemical indicator and  bowie dick test pack ? Chemical indicator are either physical or chemical devices used to monitor one or more of the process parameters of the sterilization cycle. Currently they are divided into 6 classifications. They are as follows:  Class 1: Process indicators areintended for use with individual items, e.g., containers, to indicate that the unit has been directly exposed to the sterilization process and to distinguish between processed and nonprocessed items. Indicator tapes, indicator labels and load cards are examples of externally visible chemical indicators that are on the outside on the packages.  Class 2: Indicators are intendedfor use in specific test procedures as defined in relevant sterilizer/ sterilization control standards. . Bowie-Dicks are one type of specific testing most are familiar with. These are used to show the efficacy of air removal and steam penetration.  Class 3: A single variableindicator that is designed to solely show the exposure to one Sterilization control products process at a stated value (SV) of the chosen variable. One example of a single variable is a temperature tube that houses a chemical pellet which melts at a specific temperature.  Class 4: These are considered asmultiple variable indicators. They are designed to react with two or more of the critical variables and are intended to indicate exposure to a sterilization cycle at SVs of the chosen variable. Examples of these class 4 would be the paper strips with a color change chemical indicator. These are usually used inside each package.  Class 5: Integrating indicatorsare designed to react with all critical variables. These can be used as internal chemical indicators in all packs and containers for pack control monitoring. They can also be used as an additional monitoring tool in order to be able to release loads that do not contain implants based on the appropriate Process Challenge Device. These indicators can also be used in implant loads IF a Biological Indicator is run with the class 5 integrator. The load can NOT be released until the BI result is known except in emergencies.  Class 6: These are calledemulating Indicators which are cycle verification indicators which are designed to react to all critical variables for specified sterilization cycles. In other words they are considered to be indicative of a complete cycle by showing the presence or absence of specific time and temperature parameters during a cycle. They are currently only available in the US for steam sterilization. Chemical indicator are convenient, are inexpensive, and indicate that the item has been exposed to the sterilization process. In one study, chemical indicators were more likely than  biological indicators toinaccurately indicate sterilization at marginal sterilization times (e.g., 2 minutes). Steam Chemical indicators shouldbe used in conjunction with biological indicators, but based on current studies should not replace them because they indicate sterilization at marginal sterilization time and because only a biological indicator consisting of resistant spores can measure the microbial killing power of the sterilization process. Chemical indicators are affixed on the outside of each pack to show that the package has been processed through a sterilization cycle, but these indicators do not prove sterilization has been achieved. Preferably, a chemical indicator also should be placed on the inside of each pack to verify sterilant penetration. Chemical indicators usually are either heat-or chemicalsensitive inks that change color when one or more sterilization parameters (e.g., steam-time, temperature, and/or saturated steam; ETO-time, temperature, relative humidity and/or ETO concentration) are present.  Chemical indicators have beengrouped into five classes based on their ability to monitor one or multiple sterilization parameters. If the internal and/or external indicator suggests inadequate processing, the item should not be used An air-removal test (Bowie-Dick Test) must be performed daily in an empty dynamic-air-removal sterilizer (e.g., prevacuum steam sterilizer) to ensure air removal. The definitions listed above were taken from the ANSI/AAMI/ISO 11140-1:2005 definitions. Definitions:  Chemical indicator evice for monitoring a sterilization process. The device is designed to respond with a characteristic chemical or physical change to one or more of the physical conditions within the sterilizing chamber. Chemical indicators are intended to detect potential sterilization failures that could result from incorrect packaging, incorrect loading of the sterilizer, or malfunctions of the sterilizer. The “pass” response of a chemical indicator does not prove the item accompanied by the indicator is necessarily sterile. The Association for the Advancement of Medical Instrumentation has defined five classes of chemical indicators: Class 1 (process indicator); Class 2 (Bowie dick test pack indicator); Class 3 (single-parameter indicator); Class 4 (multi-parameter indicator); and Class 5 (integrating indicator).
  31. asd Apr 24, 2018
    I have just opened my own blog to convey this sort of thing from my own understanding. Goodluck on your website. I hope to link to your website if my content needs more support. sarkari naukri

    Leave a comment