linuse
Sep 11, 2012
  20457
(5 votes)

EPiServer 7: Configuring editors for your properties

There is an updated version of this blog post for EPiServer 7.5 here.

In EPiServer 7, one of the goals for the new editing system has been to reduce the need to create custom properties. David Knipe has written an excellent blog post about using standard validation attributes. I wrote another blog post that explains how you create a custom editor in the EPiServer 7 preview release.

Since the preview release we have done some improvements that you might want to be aware of. First of all, editors are assigned to your value types and not your property types. For instance, the editor to select pages is connected to the PageReference type and not PropertyPageReference. One problem that comes with this change is that you might have several properties that have the same value type, for instance string, but that should behave differently. This has been solved by a new attribute, “EditorHint”, that you can assign to your model properties or PropertyData-derived classes. The following example shows how one of the built in properties that uses string as the value type is defined:

   1: [EditorHint("ImageUrl")]
   2: public class PropertyImageUrl : PropertyFileUrl

We have also made some additions to be able to easily create select lists or check box selections without having to create a custom editor. This can be done doing two things. First you have to assign a type that implements ISelectionFactory to the editing meta data. Then you have to assign one of the two built in editing widgets. The following example shows a page type model with two properties that enables single or multiple selection of languages:

   1: using System;
   2: using System.Collections.Generic;
   3: using System.ComponentModel.DataAnnotations;
   4: using EPiServer.Core;
   5: using EPiServer.DataAbstraction;
   6: using EPiServer.Framework.DataAnnotations;
   7: using EPiServer.Shell.ObjectEditing;
   8: using EPiServer.Shell.ObjectEditing.EditorDescriptors;
   9:  
  10: namespace EPiServer.Templates.Alloy.Models.Pages
  11: {
  12:     [SiteContentType(
  13:         GUID = "AAC25733-1D21-4F82-B031-11E626C91E3B",
  14:         GroupName = Global.GroupNames.Specialized)]
  15:     public class TestEditorsPage : PageData
  16:     {
  17:         [Display(GroupName = SystemTabNames.Content)]
  18:         [UIHint("CustomLanguage")]
  19:         public virtual string SingleLanguage { get; set; }
  20:  
  21:         [Display(GroupName = SystemTabNames.Content)]
  22:         [UIHint("CustomLanguageMultiple")]
  23:         public virtual string MultipleLanguage { get; set; }
  24:     }
  25:  
  26:     [EditorDescriptorRegistration(TargetType = typeof(string), UIHint = "CustomLanguageMultiple")]
  27:     public class LanguageEditorDescriptor : EditorDescriptor
  28:     {
  29:         public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
  30:         {
  31:             SelectionFactoryType = typeof(LanguageSelectionFactory);
  32:             ClientEditingClass = "epi-cms/contentediting/editors/CheckBoxListEditor";
  33:  
  34:             base.ModifyMetadata(metadata, attributes);
  35:         }
  36:     }
  37:  
  38:     public class LanguageSelectionFactory : ISelectionFactory
  39:     {
  40:         public IEnumerable<ISelectItem> GetSelections(ExtendedMetadata metadata)
  41:         {
  42:              var languages = new List<SelectItem>();
  43:             languages.Add(new SelectItem(){ Value = "EN", Text = "English"});
  44:             languages.Add(new SelectItem(){ Value = "SW", Text = "Swahili"});
  45:             languages.Add(new SelectItem(){ Value = "PF", Text = "French Polynesia"});
  46:  
  47:             return languages;
  48:         }
  49:     }
  50:  
  51:     [EditorDescriptorRegistration(TargetType = typeof(string), UIHint = "CustomLanguage")]
  52:     public class LanguageMultipleEditorDescriptor : EditorDescriptor
  53:     {
  54:         public override void ModifyMetadata(ExtendedMetadata metadata, IEnumerable<Attribute> attributes)
  55:         {
  56:             SelectionFactoryType = typeof(LanguageSelectionFactory);
  57:             ClientEditingClass = "epi-cms/contentediting/editors/SelectionEditor";
  58:  
  59:             base.ModifyMetadata(metadata, attributes);
  60:         }
  61:     }
  62: }

And this is how it looks while editing pages:

SelectionFactoryScreenShot

Sep 11, 2012

Comments

Mari Jørgensen
Mari Jørgensen Sep 12, 2012 08:57 AM

Haven't you switched the classes and labels here? "SingleLanguage" should be related to the dropdown and the "MultipleLanguage" to the checkboc list.
Or am I missing something? :)







Sep 12, 2012 09:10 AM

Thanks for pointing that out Mari! I have updated the code and image to correct the mistake.

Mari Jørgensen
Mari Jørgensen Sep 12, 2012 12:35 PM

And thanks for the sample code. Already in use in a project :)

Nov 1, 2012 03:27 PM

How could you enhance the code to target a Language type rather then a string?

Thanks

Nov 2, 2012 09:56 AM

Check out the new Alloy template package. It has an example of a custom property with a custom value type that is a collection of strings.

Nov 21, 2012 07:51 AM

Updated sample code to use UiHint instead of EditorHint where appropriate.

Dzulqarnain Nasir
Dzulqarnain Nasir Nov 22, 2012 09:48 AM

Thanks for the code!

kayvan shaabani
kayvan shaabani Dec 4, 2012 02:11 PM

Thanks for the post!
Do you know how to create custom properties in EpiServer 7? Is the conventional way in Epi6 still the way forward? I mean custom properties which are complex properties and how to handle the user interface for them (such as CreateDefaultControls() , CreateEditControls() etc.)

Dec 4, 2012 04:28 PM

I have written a blog post about how to create native properties in a later blog post in this series: http://world.episerver.com/Blogs/Linus-Ekstrom/Dates/2012/11/Creating-a-more-advanced-property-editor/

You can also add an UIHint (just add whatever that does not exist) and the legacy editing system will use your PropertyDataControl-derived type inside a dialog.

Vincent
Vincent Apr 3, 2013 09:07 AM

Hi Lius

the above example did the job, however if I have a lot of checkboxes, it looks so urgly. What I want to achieve is to create a similiar control looks like the episerver 7 "category" UI, and display all my checkboxes in that popup, can you show me a correct path how to implement it?

rasmus@mediaworkers.dk
rasmus@mediaworkers.dk Apr 17, 2013 07:30 PM

Hi,
Great article!

It's important to notice that in the ISelectionFactory the value of the SelectItems returned MUST be a string. I fell for the temptation using an integer but ran into problems. The data was saved in the database correctly, but when I opened the page again, the editor could not preselect the checkboxes.

Tarjei Olsen
Tarjei Olsen Apr 26, 2013 12:30 PM

After patching up to version 7.1 pages with properties that render check box lists via the ClientEditingClass="epi.cms.contentediting.editors.CheckBoxListEditor" no longer loads in the "forms" edit mode. Nothing happens when I click on the edit-button. If I change ClientEditingClass to "epi.cms.contentediting.editors.SelectionEditor" I am allowed to enter edit mode, but I need to be able to select multiple items. Anyone else having this problem after upgrading to 7.1?

Apr 26, 2013 12:41 PM

There was some changes due to the fact that we upgraded Dojo to 1.8 that you need to be aware of and change. First, the root namespace "epi/cms" was changed to "epi-cms" since / can no longer be in a root namespace. The second is that templates now have slash-notation for types, for instance /dijit/form/textbox instead of "dijit.form.textbox". You can read more about it here: http://world.episerver.com/en/Documentation/Items/Release-Notes/EPiServer-CMS/EPiServer-7/Release-Notes--EPiServer-7-1-CMS/?id=66142&epslanguage=en

Tarjei Olsen
Tarjei Olsen Apr 26, 2013 01:57 PM

Ok, thanks for the tip and the fast response – I really appreciate it. I was a bit thrown off by the fact that my custom drop down lists worked while the check box lists did not.

I changed the client editing mode css class to "epi-cms/contentediting/editors/CheckBoxListEditor" and "epi-cms/contentediting/editors/SelectionEditor" now, and it all works again. A great way to end this friday’s coding!

Calle Bjernekull
Calle Bjernekull Sep 12, 2013 10:15 AM

I cannot switch to "Form editing" after I implemented this code. Just like Tarjei, I changed the class to epi-cms/contentediting/editors/CheckBoxListEditor because I'm running 7.1.
I get a 404-error when trying to load http://[my-site-host]/episerver/Shell/1.0.456/ClientResources/dtk/epi-cms/contentediting/editors/CheckBoxListEditor.js

tobias.gladh@knowit.se
tobias.gladh@knowit.se Oct 23, 2013 09:29 AM

Same error as Calle. Solved this on the StringList custom property from the alloy site but have no clue on how to solve this since it is EPiServer built in dojo reference.

The solution to the StringList was in the module.config, don't know if this is the way in this case also?

tobias.gladh@knowit.se
tobias.gladh@knowit.se Oct 31, 2013 10:03 AM

Solution for me was that I've missed that I didn't had CMS 7.1 so first I changed it to epi.cms/contentediting/editors/CheckBoxListEditor.

After the upgrade it all works as expected with epi-cms/contentediting/editors/CheckBoxListEditor

Martin Lannsjö
Martin Lannsjö Dec 19, 2013 03:43 PM

Is there an editor for multiple select not using radiobuttons? We have a very large list of tags that work better with a multipleselect than radiobuttons. I would like to do something like this with the multiple select: http://harvesthq.github.io/chosen/

Dec 20, 2013 08:58 AM

@Martin: There is no such editor built into EPiServer but there seems to be a Dijit widget that you should be able to use: http://dojotoolkit.org/reference-guide/1.8/dijit/form/MultiSelect.html

Martin Lannsjö
Martin Lannsjö Dec 20, 2013 09:10 AM

Thanks @Linus, I will look into that.

Jonathan Roberts
Jonathan Roberts Apr 15, 2019 01:02 PM

Hi,

Is this possible in Episerver 6 R2? I would like to hide the Shotcut tab from the CMS

Thanks

Jon

linuse
linuse Apr 15, 2019 04:17 PM

Hi Jonathan,

Sorry, but this code is relevant to version 7 and above only. Episerver version 6 and older use a totally different editor interface, with much more limitations. I think that a tab can be hidden by setting access rights to a certain group, but other from that I don't actually know. Perhaps it's time for the customer to upgrade to a newer version.-..

Regards
Linus

Please login to comment.
Latest blogs
Plug-in manager is back in CMS 12

Plug-in manager is back in the UI, what is it and how can i use it?

Luc Gosso (MVP) | Oct 6, 2022 | Syndicated blog

Display Child Pages in Content Delivery API Response

The below example will implement an instance of IContentConverterProvider to customise the serialisation of PageData and output child pages in the...

Minesh Shah (Netcel) | Oct 4, 2022

Bring the Report Center back in Optimizely CMS 12

The Report Center has been a part of Optimizely CMS since its first debut in version 5R2 in 2008, but in CMS 12, it's removed! Don't despair! Make...

Tomas Hensrud Gulla | Oct 4, 2022 | Syndicated blog

Customizing Property Lists in Optimizely CMS

Generic property lists is a cool editorial feature that has gained a lot of popularity - in spite of still being unsupported (officially). But if y...

Allan Thraen | Oct 2, 2022 | Syndicated blog

Optimizely names Luminary Senior Developer, Ynze Nunnink, OMVP

Luminary Senior Developer and Optimizely Lead, Ynze Nunnink has secured the coveted position of Optimizely MVP. Earning a Platinum badge for his...

Ynze | Oct 2, 2022 | Syndicated blog

Content Delivery API – The Case of the Duplicate API Refresh Token

Creating a custom refresh provider to resolve the issues with duplicate tokens in the DXC The post Content Delivery API – The Case of the Duplicate...

David Lewis | Sep 29, 2022 | Syndicated blog