Custom Content Part of Widget appearing twice

Topics: Customizing Orchard, Writing modules
Jan 8 at 1:23 PM
I've created a Content Part in code and transformed it into a Widget.
For some reason, the editor is showing twice, but the result as well.
One of the rendered forms (fields) is the one that is controlled by my Driver and actually updates fields in the database, the other one... well, doesn't.

This is the result:
Image

I have absolutely no idea as to why it still shows the first set of fields. When looking in the database, these fields do not seem to be stored in my table neither (however, they are rendered as part of the Widget).

Below is the code used:

Models

public class EventListViewRecord : ContentPartRecord
    {
        public virtual string CssId { get; set; }
        public virtual int NumberOfEvents { get; set; }
        public virtual string EventListViewType { get; set; }
        public virtual bool LazyLoading { get; set; }
    }

    public class EventListViewPart : ContentPart<EventListViewRecord>
    {
        [Required]
        public int NumberOfEvents 
        {
            get { return Retrieve(f => f.NumberOfEvents); }
            set { Store(f => f.NumberOfEvents, value); } 
        }

        [Required]
        public string EventListViewType
        {
            get { return Retrieve(f => f.EventListViewType); }
            set { Store(f => f.EventListViewType, value); }
        }

        [Required]
        public string CssId
        {
            get { return Retrieve(f => f.CssId); }
            set { Store(f => f.CssId, value); }
        }

        public bool LazyLoading
        {
            get { return Retrieve(f => f.LazyLoading); }
            set { Store(f => f.LazyLoading, value); }
        }
    }

Driver

public class EventListViewDriver : ContentPartDriver<EventListViewPart>
    {
        protected override string Prefix
        {
            get
            {
                return "MyCustomPrefix";
            }
        }
        protected override DriverResult Display(EventListViewPart part, string displayType, dynamic shapeHelper)
        {
            return ContentShape("Parts_EventListView", () => shapeHelper.Parts_EventListView(
                CssId: part.CssId,
                NumberOfEvents: part.NumberOfEvents,
                EventListViewType: part.EventListViewType,
                LazyLoading: part.LazyLoading));

        }

        ////GET
        protected override DriverResult Editor(
            EventListViewPart part, dynamic shapeHelper)
        {
            return ContentShape("Parts_EventListView_Edit",
                () => shapeHelper.EditorTemplate(
                    TemplateName: "Parts/EventListView",
                    Model: part,
                    Prefix: Prefix));
        }
        //POST
        protected override DriverResult Editor(
            EventListViewPart part, IUpdateModel updater, dynamic shapeHelper)
        {
            updater.TryUpdateModel(part, Prefix, null, null);
            return Editor(part, shapeHelper);
        }
    }

EditorView ()

@model MyNamespace.Models.EventListViewPart


<fieldset>
    <legend>Map Fields</legend>

    <div class="editor-label">
        @Html.LabelFor(model => model.CssId)
    </div>
    <div class="editor-field">
        @Html.TextBoxFor(model => model.CssId)
        @Html.ValidationMessageFor(model => model.CssId)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.EventListViewType)
    </div>
    <div class="editor-field">
        @Html.DropDownListFor(model => model.EventListViewType, viewTypeOptions)
        @Html.ValidationMessageFor(model => model.EventListViewType)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.NumberOfEvents)
    </div>
    <div class="editor-field">
        @Html.TextBoxFor(model => model.NumberOfEvents)
        @Html.ValidationMessageFor(model => model.NumberOfEvents)
    </div>

    <div class="editor-label">
        @Html.LabelFor(model => model.LazyLoading)
    </div>
    <div class="editor-field">
        @Html.CheckBoxFor(model => model.LazyLoading)
        @Html.ValidationMessageFor(model => model.LazyLoading)
    </div>

</fieldset>

Placement.info

<Placement>
  <Place Parts_EventListView="Content:1"/>
  <Place Parts_EventListView_Edit="Content:7.5"/>
</Placement>

Migrations.cs

public int Create()
        {
//create table
            SchemaBuilder.CreateTable(typeof(EventListViewRecord).Name,
                table => table
                    .ContentPartRecord()
                    .Column("CssId", DbType.String)
                    .Column("EventListViewType", DbType.String)
                    .Column("NumberOfEvents", DbType.Int32)
                    .Column("LazyLoading", DbType.Boolean));

            //create part
            ContentDefinitionManager.AlterPartDefinition(typeof(EventListViewPart).Name, builder => builder
                .Attachable(true)
                .WithField("CssId", field => field
                                            .OfType("TextField")
                                            .WithDisplayName("CssId"))
                .WithField("EventListViewType", field => field
                                            .OfType("EnumerationField")
                                            .WithDisplayName("Select Event List View Type")
                                            .WithSetting("EnumerationFieldSettings.Required", "True")
                                            .WithSetting("EnumerationFieldSettings.Options", String.Join(
                                                Environment.NewLine, MyNamespace.Globals.Picklists.EventListViewTypes))
                                            .WithSetting("EnumerationFieldSettings.ListMode", "Dropdown"))
                .WithField("NumberOfEvents", field => field
                                            .OfType("NumericField")
                                            .WithDisplayName("Number of events")
                                            .WithSetting("NumericFieldSettings.Required", "True")
                                            .WithSetting("NumericFieldSettings.Scale", "0")
                                            .WithSetting("NumericFieldSettings.Minimum", "0")
                                            .WithSetting("NumericFieldSettings.Maximum", "100"))
                .WithField("LazyLoading", field => field
                                            .OfType("BooleanField")
                                            .WithDisplayName("Enable Lazy Loading"))
                                            );

            //create widget with unique name
            ContentDefinitionManager.AlterTypeDefinition(typeof(EventListViewPart).Name, cfg => cfg
                                                                                    .WithPart(typeof(EventListViewPart).Name)
                                                                                    .WithPart("WidgetPart")
                                                                                    .WithPart("CommonPart")
                                                                                    .WithSetting("Stereotype", "Widget")
                                                                                    );

            return 1;
        }
I've tried choosing separate names for the widget and the content part, but to no avail. I actually wouldn't have a problem with the upper fields (see image) being rendered, if they were saved to the database as well so I didn't need to use the custom Editor Templates...

Does anyone have an idea? I've been looking at this for more than 2 days straight and it's driving me mad!
Jan 8 at 2:14 PM
This Orchard Discussion Boad really helps! Shortly after typing this post and actually summarizing the code, I realised I was created the fields twice in my Migration.cs file.
As the fields are created in the database through the SchemaBuilder.CreateTable statement, I do not have to create the ContentPart with the .WithField statements.

This is my new Migrations.cs file:
public int Create()
        {
//create table
            SchemaBuilder.CreateTable(typeof(EventListViewRecord).Name,
                table => table
                    .ContentPartRecord()
                    .Column("CssId", DbType.String)
                    .Column("EventListViewType", DbType.String)
                    .Column("NumberOfEvents", DbType.Int32)
                    .Column("LazyLoading", DbType.Boolean));

            //create part
            ContentDefinitionManager.AlterPartDefinition(typeof(EventListViewPart).Name, builder => builder
                .Attachable(true);

            //create widget with unique name
            ContentDefinitionManager.AlterTypeDefinition(typeof(EventListViewPart).Name, cfg => cfg
                                                                                    .WithPart(typeof(EventListViewPart).Name)
                                                                                    .WithPart("WidgetPart")
                                                                                    .WithPart("CommonPart")
                                                                                    .WithSetting("Stereotype", "Widget")
                                                                                    );

            return 1;
        }