---
title: Editor templates
slug: cms-11/dev-docs/editor-templates
docTags: 
createdAt: 2026-07-22T19:45:18.000Z
---

If you want further control over how you render the user interface, you can add an editor template for your class by creating a partial MVC view and naming the view as your model, such as `{nameOfMyModelClass}.ascx`. The application can look for the view in two places:

- If your criterion is part of a registered module, the first search path is:
  `{yourModuleRoot}/Views/Shared/EditorTemplates/{nameOfMyModelClass}.ascx`
- If you do not find the view in the module folder or if your criterion is not part of a module, the next search path is:
  `~/Views/Shared/EditorTemplates/{nameOfYourModelClass}.ascx`

In your editor template, you can import the `EPiServer.Personalization.VisitorGroups` to the `DojoEditorFor` method. The `DojoEditorFor` method creates a widget that handles the loading and saving of values from or to a specified model class property. `DojoWidgetFor` discovers and makes use of any `DojoWidget` attribute settings for model class properties. If you do not use `DojoWidgetFor` to create edit controls for your properties, you must handle the loading and saving of values yourself.

The following editor template shows an example using the `DojoWidgetFor` method, which uses two different overloads. The first call only specifies the name of the model class attribute; the second call uses the overload with the most parameters. A full range of overload exists between these two extremes.

```csharp
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<YourModelClass>" %>
  <%@ Import Namespace="EPiServer.Personalization.VisitorGroups" %>
  <div>
    <span>
      <%= Html.DojoEditorFor(p => p.ModelClassProperty1)%>
    </span>
    <span>
      <%= Html.DojoEditorFor(
        p => p.ModelClassProperty2, 
        new {
              @class = "WidgetCssClass", 
              @someOtherHtmlAttribute = "value" 
            },
        "WidgetLabelText",
        "WidgetLabelCssClass",
        DojoHtmlExtensions.LabelPosition.Right)
      %>
    </span>
  </div>
```

## Custom script

The `VisitorGroupCriterion` attribute has a `ScriptUrl` property, where you can specify a script file used when creating the settings user interface. The `ScriptUrl` should contain a JavaScript object that overrides one or more of the following methods:

- `createUI()` – Called to create the user interface for the criterion.
- `validate` – Called when you try to save a visitor group.
- `getSettings` – Called when you save the visitor group to gather the data to save.
- `uiCreated` – Raises an event when you create the user interface.

The following script shows an example that overrides these methods:

```csharp
(function () {
    return {
      // Add an extra div to the layout.
      // prototype.createUI is called to make sure
      // that the autogenerated elements are added too.
      createUI: function (namingContainerPrefix, container, settings) {
        this.prototype.createUI.apply(this, arguments);
        var element = dojo.create('div', {
          id: namingContainer + 'MyDiv'
        });
        element.innerHTML = "This is MyDiv";
        dojo.place(element, container);
      },
      // Add a validation error message if the value of MyInt is > 1000.
      // prototype.validate is called so that we don't hide errors
      // added by the default validators.
      // See also Client Side Validation to see how you can provide
      // localized strings - like error messages.
      validate: function (namingContainer) {
        var validationErrors = this.prototype.validate.apply(this, arguments);
        var myIntWidget = dijit.byId(namingContainer + 'MyInt');
        if (myIntWidget.value > 1000) {
          validationErrors.Add('Error!', myIntWidget.domNode.id);
        }
        return validationErrors;
      },
      // Multiply the value of MyInt by 10 before saving.
      getSettings: function (namingContainer) {
        var myIntValue = dijit.byId(namingContainer + 'MyInt').value;
        // Attach eventhandler for onmouseover.
        // The settings parameter passed to the function contains
        // the model properties and values. It is not used in this
        // example but you could, for example, retrieve the current
        // value of MyInt via settings.MyInt.
        uiCreated: function (namingContainer, setting) {
          var myIntWidget = dojo.byId(namingContainer + 'MyInt');
          dojo.connect(myIntWidget,
            'onmouseover',
            null,
            function () {
              alert('You hovered over the MyInt field.');
            }
          );
        }
      }
    }
  )();
```
