<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Blog posts by Duong Nguyen</title><link href="http://world.optimizely.com" /><updated>2014-01-20T11:22:24.0000000Z</updated><id>https://world.optimizely.com/blogs/Duong-Nguyen/</id> <generator uri="http://world.optimizely.com" version="2.0">Optimizely World</generator> <entry><title>Country-Region drop down lists in All properties mode</title><link href="https://world.optimizely.com/blogs/Duong-Nguyen/Dates/2014/1/Country-Region-drop-down-lists-in-All-properties-mode/" /><id>&lt;p&gt;I have gotten quite a few questions from both the forum and developer support regarding how to populate a drop down list depends on value of another drop down list in All Properties mode. In a recent blog post, my colleague Linus Ekstr&#246;m has mentioned a possible solution by using FormContainer to create a custom editor for the country/region block. In this post, I will present a working example using another approach which in my opinion is more lightweight and more conformal to the architecture behind the All Properties mode.&lt;/p&gt;
&lt;h1&gt;All Properties mode overview&lt;/h1&gt;
&lt;p&gt;In EPiServer 7, All Properties mode (formerly know as Form editing mode) is built upon the object editing framework which was designed to be highly extensible and customizable.&lt;/p&gt;
&lt;div&gt;
&lt;p&gt;&lt;a href=&quot;/link/31bd9d5288d34882993ac3ff5a722d7c.png&quot;&gt;&lt;img style=&quot;border: 0px currentcolor; display: inline; background-image: none;&quot; title=&quot;ObjectEditing&quot; src=&quot;/link/4a6be5084408445d8dc8ba5bba308fcc.png&quot; alt=&quot;ObjectEditing&quot; width=&quot;484&quot; height=&quot;561&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The very core server side part of the Object Editing framework is the Metadata provider which inspect the edited object’s and return its metadata. We have different metadata providers for different kinds of object. For example, the annotation based metadata provider for plain C# objects or the content metadata provider for EPiServer’s content objects. All the metadata providers allow developers to extend the generated metadata by implementing metadata extenders. You might have been familiar with editor descriptors which basically are metadata extenders.&lt;/p&gt;
&lt;p&gt;On the client side, FormContainer is the central piece. It responsible for creating the entire UI from the retrieved metadata via the Widget Factory. The created structure consists of not only the editor widgets but also the layout containers. The FormContainer does not care how are the widgets arranged and how do they interact with each other. Those responsibilities are delegated to the layout containers. We have 2 types of layout containers: object container and group container. For a better imagination, please have a look at the following examples:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/link/5cfe338a4cc746a580c0fcd6c9f24619.png&quot;&gt;&lt;img style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; title=&quot;containers1&quot; src=&quot;/link/5184dadaf8b54a63a4040eb2955000a7.png&quot; alt=&quot;containers1&quot; width=&quot;448&quot; height=&quot;224&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Example 1: Layout containers for pages and shared blocks. Object container is the tab container and group containers are the tab pages&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/link/e38e7499e4f5489c8e99013da9b25643.png&quot;&gt;&lt;img style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; title=&quot;containers2&quot; src=&quot;/link/ad9b3cc69fe1434e8eaf0e9a31515358.png&quot; alt=&quot;containers2&quot; width=&quot;450&quot; height=&quot;210&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Example 2: Layout containers for block properties (complex properties). Both object container and group containers are a simple flow container with a title bar.&lt;/p&gt;
&lt;p&gt;The key point here is that we can configure which container type to be used for both object level and group level. This can be done by changing some certain settings in a metadata extender.&lt;/p&gt;
&lt;h1&gt;The country-region dropdown lists problem&lt;/h1&gt;
&lt;p&gt;In this section, I will go through an example on how to re-populate the region drop down list according to the selected country.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/link/3fe8f7fc3cda4475ae14373441f8f490.png&quot;&gt;&lt;img style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; title=&quot;country-region&quot; src=&quot;/link/0fda58701959462b9bdd3f8c588020c4.png&quot; alt=&quot;country-region&quot; width=&quot;502&quot; height=&quot;106&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Location block&lt;/h2&gt;
&lt;p&gt;Let’s start with a block type consists of 2 properties Country and Region.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;[ContentType(AvailableInEditMode=&lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;)]
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; LocationBlock : BlockData
{
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Country { get; set; }

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Region { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that we mark the content type as not available in edit mode since we will only use the block type for complex properties.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;[ContentType]
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; TestPage : PageData
{
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;virtual&lt;/span&gt; LocationBlock Location { get; set; }
}
  &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the edit mode we can see 2 text boxes. To tell EPiServer to use dropdown lists instead, we need create selection factories and assign them to the properties using the SelectOne attribute.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;&lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Country : ISelectItem
{
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; CountryCode { get; set; }
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Name { get; set; }
        
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Text 
    { 
        get 
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; Name;
        }
    }

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; Value 
    { 
        get
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; CountryCode;
        }
    }
}

&lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; Region : ISelectItem
{
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; CountryCode { get; set; }
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; RegionCode { get; set; }
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Name { get; set; }
        
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Text 
    { 
        get
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; Name;
        }
    }

    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;object&lt;/span&gt; Value
    {
        get
        {
            &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; String.Format(&lt;span class=&quot;str&quot;&gt;&quot;{0}-{1}&quot;&lt;/span&gt;, CountryCode, RegionCode);
        }
    }
}


&lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; CountrySelectionFactory : ISelectionFactory
{
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; IEnumerable&amp;lt;ISelectItem&amp;gt; GetSelections(ExtendedMetadata metadata)
    {
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Country[] 
        {
            &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Country() { CountryCode = &lt;span class=&quot;str&quot;&gt;&quot;US&quot;&lt;/span&gt;, Name = &lt;span class=&quot;str&quot;&gt;&quot;United States&quot;&lt;/span&gt; },
            &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Country() { CountryCode = &lt;span class=&quot;str&quot;&gt;&quot;SE&quot;&lt;/span&gt;, Name = &lt;span class=&quot;str&quot;&gt;&quot;Sweden&quot;&lt;/span&gt; }
        };
    }
}


&lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; RegionSelectionFactory : ISelectionFactory
{
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; IEnumerable&amp;lt;ISelectItem&amp;gt; GetSelections(ExtendedMetadata metadata)
    {
        &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Region[]
        {
            &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Region() { CountryCode = &lt;span class=&quot;str&quot;&gt;&quot;US&quot;&lt;/span&gt;, RegionCode = &lt;span class=&quot;str&quot;&gt;&quot;NY&quot;&lt;/span&gt;, Name = &lt;span class=&quot;str&quot;&gt;&quot;New York&quot;&lt;/span&gt; },
            &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Region() { CountryCode = &lt;span class=&quot;str&quot;&gt;&quot;US&quot;&lt;/span&gt;, RegionCode = &lt;span class=&quot;str&quot;&gt;&quot;CA&quot;&lt;/span&gt;, Name = &lt;span class=&quot;str&quot;&gt;&quot;California&quot;&lt;/span&gt; },

            &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Region() { CountryCode = &lt;span class=&quot;str&quot;&gt;&quot;SE&quot;&lt;/span&gt;, RegionCode = &lt;span class=&quot;str&quot;&gt;&quot;AB&quot;&lt;/span&gt;, Name = &lt;span class=&quot;str&quot;&gt;&quot;Stockholm&quot;&lt;/span&gt; },
            &lt;span class=&quot;kwrd&quot;&gt;new&lt;/span&gt; Region() { CountryCode = &lt;span class=&quot;str&quot;&gt;&quot;SE&quot;&lt;/span&gt;, RegionCode = &lt;span class=&quot;str&quot;&gt;&quot;O&quot;&lt;/span&gt;, Name = &lt;span class=&quot;str&quot;&gt;&quot;V&#228;stra G&#246;taland&quot;&lt;/span&gt; }
        };
    }
}
  &lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;[ContentType(AvailableInEditMode=&lt;span class=&quot;kwrd&quot;&gt;false&lt;/span&gt;)]
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; LocationBlock : BlockData
{
    [SelectOne(SelectionFactoryType = &lt;span class=&quot;kwrd&quot;&gt;typeof&lt;/span&gt;(CountrySelectionFactory))]
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Country { get; set; }

    [SelectOne(SelectionFactoryType = &lt;span class=&quot;kwrd&quot;&gt;typeof&lt;/span&gt;(RegionSelectionFactory))]
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Region { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So far so good. We have got 2 drop down list for our properties. However they are not inter-connected so user can still chose country as Sweden and region as California! Make no sense?&lt;/p&gt;
&lt;h2&gt;FilterableSelectionEditor&lt;/h2&gt;
&lt;p&gt;When we mark the property with SelectOne attribute, it will use the built-in widget SelectionEditor. Unfortunately, this widget doesn’t support filtering the available options. We need to extend it a little bit:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;define([
    &lt;span class=&quot;str&quot;&gt;&quot;dojo/_base/declare&quot;&lt;/span&gt;,
    &lt;span class=&quot;str&quot;&gt;&quot;dojo/_base/array&quot;&lt;/span&gt;,

    &lt;span class=&quot;str&quot;&gt;&quot;epi-cms/contentediting/editors/SelectionEditor&quot;&lt;/span&gt;
],
&lt;span class=&quot;kwrd&quot;&gt;function&lt;/span&gt; (
    declare,
    array,

    SelectionEditor
) {

    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; declare([SelectionEditor], {
        _allOptions: &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;,

        filter: &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;,

        _setOptionsAttr: &lt;span class=&quot;kwrd&quot;&gt;function&lt;/span&gt; (options) {
            &lt;span class=&quot;rem&quot;&gt;// summary: set the options&lt;/span&gt;

            &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._allOptions = options;

            &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.inherited(arguments, [array.filter(options, &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.filter || &lt;span class=&quot;kwrd&quot;&gt;function&lt;/span&gt; () {
                &lt;span class=&quot;rem&quot;&gt;// return all options if no filter function provided.&lt;/span&gt;
                &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;true&lt;/span&gt;;
            }, &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;)]);
        },

        _setFilterAttr: &lt;span class=&quot;kwrd&quot;&gt;function&lt;/span&gt; (filter) {
            &lt;span class=&quot;rem&quot;&gt;// summary: set the option filter function&lt;/span&gt;

            &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._set(&lt;span class=&quot;str&quot;&gt;&quot;filter&quot;&lt;/span&gt;, filter);

            &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.set(&lt;span class=&quot;str&quot;&gt;&quot;options&quot;&lt;/span&gt;, &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._allOptions);
        }
    });
});&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Wrap everything up&lt;/h2&gt;
&lt;p&gt;Let’s look at the diagram again. There are 2 green boxed. They are the things that we need to extend to achieve what we want. First, we need to create a custom group container for our block, then replace the default one using an editor descriptor.&lt;/p&gt;
&lt;p&gt;By default, in All properties mode, the group containers are &quot;epi/shell/layout/SimpleContainer&quot;. We just extend this container, override the addChild method and hook up the widget we are interested in. Add a new file named LocationBlockContainer under the ClientResources folder.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;define([
    &lt;span class=&quot;str&quot;&gt;&quot;dojo/_base/declare&quot;&lt;/span&gt;,
    &lt;span class=&quot;str&quot;&gt;&quot;dojo/_base/lang&quot;&lt;/span&gt;,

    &lt;span class=&quot;str&quot;&gt;&quot;epi/shell/layout/SimpleContainer&quot;&lt;/span&gt;
],
&lt;span class=&quot;kwrd&quot;&gt;function&lt;/span&gt; (
    declare,
    lang,

    SimpleContainer
) {

    &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; declare([SimpleContainer], {
        countryDropdown: &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;,
        regionDropdown: &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;,

        addChild: &lt;span class=&quot;kwrd&quot;&gt;function&lt;/span&gt; (child) {
            &lt;span class=&quot;rem&quot;&gt;// Summar: Add a widget to the container&lt;/span&gt;

            &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.inherited(arguments);
            
            &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (child.name.indexOf(&lt;span class=&quot;str&quot;&gt;&quot;country&quot;&lt;/span&gt;) &amp;gt;= 0) {
                &lt;span class=&quot;rem&quot;&gt;// If it&#39;s the country drop down list&lt;/span&gt;
                &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.countryDropdown = child;

                &lt;span class=&quot;rem&quot;&gt;// Connect to change event to update the region drop down list&lt;/span&gt;
                &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.own(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.countryDropdown.on(&lt;span class=&quot;str&quot;&gt;&quot;change&quot;&lt;/span&gt;, lang.hitch(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;, &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._updateRegionDropdown)));
            } &lt;span class=&quot;kwrd&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;if&lt;/span&gt; (child.name.indexOf(&lt;span class=&quot;str&quot;&gt;&quot;region&quot;&lt;/span&gt;) &amp;gt;= 0) {
                &lt;span class=&quot;rem&quot;&gt;// If it&#39;s the region drop down list&lt;/span&gt;
                &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.regionDropdown = child;

                &lt;span class=&quot;rem&quot;&gt;// Update the region drop down&lt;/span&gt;
                &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;._updateRegionDropdown(&lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.countryDropdown.value);
            }
        },

        _updateRegionDropdown: &lt;span class=&quot;kwrd&quot;&gt;function&lt;/span&gt; (country) {
            &lt;span class=&quot;rem&quot;&gt;// Summary: Update the region drop down list according to the selected country&lt;/span&gt;

            &lt;span class=&quot;rem&quot;&gt;// Clear the current value&lt;/span&gt;
            &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.regionDropdown.set(&lt;span class=&quot;str&quot;&gt;&quot;value&quot;&lt;/span&gt;, &lt;span class=&quot;kwrd&quot;&gt;null&lt;/span&gt;);

            &lt;span class=&quot;rem&quot;&gt;// Set the filter&lt;/span&gt;
            &lt;span class=&quot;kwrd&quot;&gt;this&lt;/span&gt;.regionDropdown.set(&lt;span class=&quot;str&quot;&gt;&quot;filter&quot;&lt;/span&gt;, &lt;span class=&quot;kwrd&quot;&gt;function&lt;/span&gt; (region) {
                &lt;span class=&quot;rem&quot;&gt;// Oops, the region code is prefixed with country code, for the simplicity&lt;/span&gt;
                &lt;span class=&quot;kwrd&quot;&gt;return&lt;/span&gt; region.value.indexOf(country) === 0;
            });
        }
    });
});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And tell EPiServer that we want to use it for the LocationBlock:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;[EditorDescriptorRegistration(TargetType = &lt;span class=&quot;kwrd&quot;&gt;typeof&lt;/span&gt;(LocationBlock))]
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;class&lt;/span&gt; LocationBlockEditorDescriptor : EditorDescriptor
{
    &lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;override&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;void&lt;/span&gt; ModifyMetadata(Shell.ObjectEditing.ExtendedMetadata metadata, IEnumerable&amp;lt;Attribute&amp;gt; attributes)
    {
        &lt;span class=&quot;kwrd&quot;&gt;base&lt;/span&gt;.ModifyMetadata(metadata, attributes);
        metadata.Properties.Cast&amp;lt;ExtendedMetadata&amp;gt;().First().GroupSettings.ClientLayoutClass = &lt;span class=&quot;str&quot;&gt;&quot;alloy/LocationBlockContainer&quot;&lt;/span&gt;;            
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Last but not least, we need to indicate that we will use the FilterableSelectionEditor for the Region property.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;[ClientEditor(ClientEditingClass = &lt;span class=&quot;str&quot;&gt;&quot;alloy/editors/FilterableSelectionEditor&quot;&lt;/span&gt;, SelectionFactoryType = &lt;span class=&quot;kwrd&quot;&gt;typeof&lt;/span&gt;(RegionSelectionFactory))]
&lt;span class=&quot;kwrd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;virtual&lt;/span&gt; &lt;span class=&quot;kwrd&quot;&gt;string&lt;/span&gt; Region { get; set; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And we are done!&lt;/p&gt;
&lt;h1&gt;Conclusion&lt;/h1&gt;
&lt;p&gt;I hope that this small example will help to explain a little bit more on how the Edit mode is built in EPiServer. It’s not a cake walk to extend at the moment but doable with not so much trouble. We will hopefully improve the public APIs and probably add more convenient methods, extension points, … in the future release to make it easier and more fun. Happy extending and overriding!&lt;/p&gt;</id><updated>2014-01-20T11:22:24.0000000Z</updated><summary type="html">Blog post</summary></entry> <entry><title>Custom views and plugin areas in EPiServer 7.5</title><link href="https://world.optimizely.com/blogs/Duong-Nguyen/Dates/2013/12/Custom-views-and-plugin-areas-in-EPiServer-75/" /><id>&lt;h1&gt;Create custom views&lt;/h1&gt;
&lt;p&gt;You might have already known that in EPiServer 7.5, it is possible to create custom views in Edit mode beside the built-in “On page edit” and “All properties” views. &lt;br /&gt;In the simplest practice, all you need is to create a widget which represent your custom view and register it on the server side using a descriptor class. &lt;br /&gt;In the below example, I will create a very simple view which simply displays the text “My very simple edit view”. The widget looks like this:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;define([
    &quot;dojo/_base/declare&quot;,

    &quot;dijit/_WidgetBase&quot;,
    &quot;dijit/_TemplatedMixin&quot;
],

function (
    declare,

    _WidgetBase,
    _TemplatedMixin
) {

    return declare([_WidgetBase, _TemplatedMixin], {
        templateString: &quot;&amp;lt;div&amp;gt;My very simple edit view&amp;lt;/div&amp;gt;&quot;,

        updateView: function (viewInfo, context) {
        }
    });
});&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Be noticed that the widget should have an updateView method, which is called when the view is loaded or updated due to context change. And here is the view configuration on the server side:&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;using EPiServer.Core;
using EPiServer.ServiceLocation;
using EPiServer.Shell;

namespace EPiServer.Templates.Alloy.Business.ViewConfigurations
{
    [ServiceConfiguration(typeof(ViewConfiguration))]
    public class SummaryView : ViewConfiguration&amp;lt;IContentData&amp;gt;
    {
        public SampleView()
        {
            Key = &quot;sampleView&quot;;
            Name = &quot;Sample View&quot;;
            Description = &quot;Very simple view&quot;;
            IconClass = &quot;epi-iconForms&quot;;

            ControllerType = &quot;alloy/views/SampleView&quot;;
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Nothing special! You provide a key, a name, a description, and an icon class for your view. The single interesting point here is the property ControllerType whose value is the module id of the widget mentioned above. You may ask why is it called Controller type while we are creating a view. The answer is that the Edit UI is design toward the MVC pattern where you have a controller widget which in turn will decide the view widget to load. In this example, for the simplicity, the controller widget does not care about the view widget as it always display the same text.&lt;/p&gt;
&lt;p&gt;Here is what we get:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/link/7677a181c4534796badceb5522bfef50.png&quot;&gt;&lt;img style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; title=&quot;blog-1&quot; src=&quot;/link/a2477cfe6bca43148a86644166376f8b.png&quot; alt=&quot;blog-1&quot; width=&quot;244&quot; height=&quot;144&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The Edit mode switch button is now a drop down menu where you can select the brand new Sample View from.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/link/c7df623b4bfa421b860acbeaf0495b20.png&quot;&gt;&lt;img style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; title=&quot;blog-2&quot; src=&quot;/link/72b60158fded4289adc8d78f7ef6ab20.png&quot; alt=&quot;blog-2&quot; width=&quot;506&quot; height=&quot;222&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And the simple view is showing up.&lt;/p&gt;
&lt;h1&gt;Plug the custom view to a pluggable area&lt;/h1&gt;
&lt;p&gt;When you have so many view, the drop down many may get crowded. Also, you may want to add your view to some other places, for instance the Tool button under the Content Settings Header, or the Publish/Option menu. This feature has unfortunately missed the train in EPiServer 7.5, but with a little bit effort, we can achieve it.&lt;/p&gt;
&lt;p&gt;If you inspected the ViewConfiguration class, you would have seen 2 properties: HideFromViewMenu and PlugInAreas. Let’s modify our sample view a bit.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;using EPiServer.Core;
using EPiServer.ServiceLocation;
using EPiServer.Shell;

namespace EPiServer.Templates.Alloy.Business.ViewConfigurations
{
    [ServiceConfiguration(typeof(EPiServer.Shell.ViewConfiguration))]
    public class SampleView : ViewConfiguration&amp;lt;IContentData&amp;gt;
    {
        public SampleView()
        {
            Key = &quot;sampleView&quot;;
            Name = &quot;Sample View&quot;;
            Description = &quot;A stupid simple view&quot;;
            ControllerType = &quot;alloy/views/SampleView&quot;;
            IconClass = &quot;epi-iconForms&quot;;

            HideFromViewMenu = true;
            PlugInAreas = new string[] { &quot;toolButton&quot; };
        }
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this configuration, we want to hide the view from the drop down menu and state that we want to plug our view to the Tool button. &lt;br /&gt;However, no magic has happened yet. To make it happened, I have created a simple command provider which inspects all the views available to the current content context and are configured to the specified plugin area. You just need to configure your plugin area in the client module initializer.&lt;/p&gt;
&lt;pre class=&quot;language-csharp&quot;&gt;&lt;code&gt;commandregistry.registerProvider(&quot;epi.cms.contentdetailsmenu&quot;, new AvailableViewsCommandProvider({
        plugInArea: &quot;toolButton&quot;
}));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The above method call registers a AvailableViewsCommandProvider with plugInArea “toolButton” to the global command provider of the Tool button whose key is “epi.cms.contentdetailmenu”. Here is the result:&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/link/61fead2520444d8c91fd461d0083812e.png&quot;&gt;&lt;img style=&quot;margin-right: auto; margin-left: auto; float: none; display: block; background-image: none;&quot; title=&quot;blog-3&quot; src=&quot;/link/cbbeaa9a1f084127acf7a9d5acdda1ee.png&quot; alt=&quot;blog-3&quot; width=&quot;244&quot; height=&quot;186&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I will let you discover the command provider by yourself. It will give you a better understanding on how the command provider/consumer pattern works in EPiServer as well as how to get informed when a view is loaded.&lt;/p&gt;
&lt;p&gt;I hope it will help you to extend the awesome EPiServer Edit UI to fit your customer’s requirements. Happy coding!&lt;/p&gt;
&lt;p&gt;Download the code for the command provider:&amp;nbsp;&lt;a href=&quot;/link/0e164517bd974d9e8d1d9e4a90309e51.zip&quot; target=&quot;_blank&quot;&gt;ViewCommandProvider.zip&lt;/a&gt;.&lt;/p&gt;
&lt;div id=&quot;scid:0767317B-992E-4b12-91E0-4F059A8CECA8:b326280e-3410-447c-afa3-edd3b41239d6&quot; class=&quot;wlWriterEditableSmartContent&quot; style=&quot;margin: 0px; padding: 0px; float: none; display: inline;&quot;&gt;Technorati Tags: &lt;a href=&quot;http://technorati.com/tags/view&quot; rel=&quot;tag&quot;&gt;view&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/edit+mode&quot; rel=&quot;tag&quot;&gt;edit mode&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/EPiServer+7.5&quot; rel=&quot;tag&quot;&gt;EPiServer 7.5&lt;/a&gt;,&lt;a href=&quot;http://technorati.com/tags/pluggability&quot; rel=&quot;tag&quot;&gt;pluggability&lt;/a&gt;&lt;/div&gt;</id><updated>2013-12-06T15:53:23.0000000Z</updated><summary type="html">Blog post</summary></entry></feed>