N-N Relation between non-content data

Topics: Troubleshooting, Writing modules
Apr 23, 2012 at 4:22 PM

Hello,

I'm trying to write new form module, I've these models;

FormItemRecord.cs;

using System.Collections.Generic;
using Orchard.Data.Conventions;

namespace MyForms.Models
{
    public class FormItemRecord
    {
        public FormItemRecord()
        {
            Forms = new List<FormRelationRecord>();
        }

        public virtual int Id { get; set; }
        public virtual string Title { get; set; }
        public virtual string Type { get; set; }
        public virtual string Options { get; set; }
        public virtual bool IsRequired { get; set; }

        public virtual IList<FormRelationRecord> Forms { get; set; }
    }
}

FormRecord.cs;

using System.Collections.Generic;
using Orchard.Data.Conventions;

namespace MyForms.Models
{
    public class FormRecord
    {
        public FormRecord()
        {
            FormItems = new List<FormRelationRecord>();
        }

        public virtual int Id { get; set; }
        public virtual string Title { get; set; }
        public virtual string FirstMessage { get; set; }
        public virtual string LastMessage { get; set; }
        public virtual string Email { get; set; }
        public virtual bool Captcha { get; set; }

        public virtual IList<FormRelationRecord> FormItems { get; set; }
    }
}

And FormRelationRecord.cs;


using
System.Collections.Generic;
namespace MyForms.Models
{
    public class FormRelationRecord
    {
        public virtual int Id { get; set; }
        public virtual FormItemRecord FormItemRecord { get; set; }
        public virtual FormRecord FormRecord { get; set; }

    }
}

 

Migration.cs ;

SchemaBuilder.CreateTable("FormRecord", table =>
                table
                    .Column<int>("Id", col => col.PrimaryKey().Identity())
                    .Column<string>("Title")
                    .Column<string>("FirstMessage")
                    .Column<string>("LastMessage")
                    .Column<string>("Email")
                    .Column<bool>("Captcha")
                    );

            SchemaBuilder.CreateTable("FormItemRecord", table =>
                table
                    .Column<int>("Id", col => col.PrimaryKey().Identity())
                    .Column<string>("Title")
                    .Column<string>("Type")
                    .Column<string>("Options")
                    .Column<bool>("IsRequired")
                    );

            SchemaBuilder.CreateTable("FormRelationRecord", table =>
                table
                    .Column<int>("Id", col => col.PrimaryKey().Identity())
                    .Column<int>("FormRecord_Id")
                    .Column<int>("FormItemRecord_Id")
                    );

 

I've implemented this and I was expecting to set relation between formItem and form itself when I add/edit new form but it's not working. What am I missing or is my structure totally wrong for NHibernate?

Coordinator
Apr 23, 2012 at 5:14 PM

You didn't show how you were using this.

Apr 24, 2012 at 8:11 AM

Here is my controller form create methods;

namespace MyForms.Controllers
{
    public class FormAdminController : Controller
    {
        private readonly ISiteService _siteService;
        private readonly IRepository<FormItemRecord> _formItemRepository;
        private readonly IRepository<FormRecord> _formRepository;
        private readonly IRepository<FormRelationRecord> _formRelationRepository;
        private readonly IOrchardServices _orchardServices;

        public FormAdminController(IOrchardServices orchardServices, ISiteService siteService, IRepository<FormRelationRecord> formRelationRepository, IRepository<FormItemRecord> formItemRepository, IRepository<FormRecord> formRepository, IShapeFactory shapeFactory)
        {
            _orchardServices = orchardServices;
            _siteService = siteService;
            _formItemRepository = formItemRepository;
            _formRepository = formRepository;
            _formRelationRepository = formRelationRepository;
            Shape = shapeFactory;
            T = NullLocalizer.Instance;
        }

        public dynamic Shape { get; set; }
        public Localizer T { get; set; }

        [Admin]
        public ActionResult Index(PagerParameters pagerParameters)
        {
            Pager pager = new Pager(_siteService.GetSiteSettings(), pagerParameters);

            var formCount = _formRepository.Table.Count();
            var forms = _formRepository.Table
                                .OrderBy(a => a.Id)
                                .Skip((pager.Page - 1) * pager.PageSize)
                                .Take(pager.PageSize)
                                .ToList();
            var pagerShape = Shape.Pager(pager).TotalItemCount(formCount);
            var viewModel = new FormIndexViewModel { Forms = forms, Pager = pagerShape };

            return View(viewModel);
        }
        

        [HttpGet, Admin]
        public ActionResult Create()
        {
            var allFormItems = _formItemRepository.Table
                                .OrderBy(a => a.Title)
                                .ToList();

            var formItems = _formRelationRepository.Table
                                .Select(m => m.FormItemRecord.Id)
                                .ToList();

            return View(new CreateFormViewModel { AllFormItems = allFormItems, FormItems = formItems });
        }

        [HttpPost, ActionName("Create"), Admin]
        public ActionResult CreatePOST(CreateFormViewModel viewModel)
        {
            if (!ModelState.IsValid)
            {
                return View(viewModel);
            }

            _formRepository.Create(new FormRecord { Title = viewModel.Title, FirstMessage = viewModel.FirstMessage, LastMessage = viewModel.LastMessage, Email = viewModel.Email, Captcha = viewModel.Captcha });
            _orchardServices.Notifier.Add(NotifyType.Information, T("Created the form {0}", viewModel.Title));
            return RedirectToAction("Index");
        }

Create View Model;

namespace MyForms.ViewModels
{
    public class CreateFormViewModel
    {
        [Required(ErrorMessage = "Title field is required")]
        public string Title { get; set; }
        public string FirstMessage { get; set; }
        public string LastMessage { get; set; }
        public string Email { get; set; }
        public bool Captcha { get; set; }
        public IEnumerable<int> FormItems { get; set; }
        public IEnumerable<FormItemRecord> AllFormItems { get; set; }
    }
}

And my view;

@using MyForms.Models
@model MyForms.ViewModels.CreateFormViewModel

<h2>New Form</h2>
@using (Html.BeginFormAntiForgeryPost("Create"))
{
    @Html.LabelFor(m => m.Title)
    @Html.TextBoxFor(m => m.Title)
    @Html.ValidationMessageFor(m => m.Title)

    @Html.LabelFor(m => m.FirstMessage)
    @Html.TextBoxFor(m => m.FirstMessage)

    @Html.LabelFor(m => m.LastMessage)
    @Html.TextBoxFor(m => m.LastMessage)

    @Html.LabelFor(m => m.Email)
    @Html.TextBoxFor(m => m.Email)

    @Html.LabelFor(m => m.Captcha)
    @Html.CheckBoxFor(m => m.Captcha)
  

    <fieldset>
    <legend>@T("Form Items")</legend>
    @Html.DropDownList("AllFormItems", new SelectList(Model.AllFormItems, "Id", "Title"), "Select Form Item to add...")
    <input type="button" id="AddItem" value="Add" />
    <ul id="itemList">
        @foreach (var itemId in Model.FormItems)
        {
            <li data-itemid="@itemId"><a href="" class="delete">X</a>  @(Model.AllFormItems.First(a => a.Id == itemId).Title)</li>
        }
    </ul>
    @foreach (var itemId in Model.FormItems)
    {
        <text>@Html.Hidden("FormItems", itemId)</text>
    }
</fieldset>

 

It's like this, I hope this shows the point that I'm missing. All I need is to set relation between form and form items after creating form itself.

Coordinator
Apr 24, 2012 at 7:58 PM

I don't see the Add method.