Complex move operations

In my app, I have a self referencing entity: Forum. It maintains a collections of child forums. Now the problem isn’t performing a move from one parent to another. That’s easy. What is severly complicating things is the presentation. I had been trying to do this in the “Edit” action, using a dropdown to list possible parents, but quickly got lost. I eventually got that part right too, but I’m not sure it’s really the right way to do it. Especially when things get even more complex at the Post level, where a post might belong to any other post in the system, as well as any other forum.

Since the operation is actually a “Move” operation, and not really an “Edit”, because the forum info itself stays the same, it just get’s reparented. Maybe I ought to make a simple Move action. But I still have a problem on how to display the choices for new possible parents for the item.

Since only admins can move forums around, and both admins and mods can move posts around, maybe I should just leave it a TextBox and have them enter the id manually? Much simpler, but requires the admin / mod know the target id.

What do you guys think?

Well that’s neither here nor there at this point since I figured out how to build a nested parent-child select list. That makes things a ton easier.

I am however, having a problem migrating my Linq2Sql repository code over to NHibernate syntax. Here’s what I currently have.

using System.Collections.Generic;
using NHibernate;
using NHibernate.Criterion;
namespace Venue.Persistence
    using FluentEngine.Persistence;
    using Venue.Domain;
    using Venue.Domain.Persistence;
    public class ForumRepository : Repository<Forum>, IForumRepository
        public IEnumerable<Forum> SelectByParentId(int? parentId)
            ICriteria criterea = session.CreateCriteria<Forum>();
            if (parentId.HasValue)
                criterea.Add(Expression.Sql("ForumId = ?", parentId, NHibernateUtil.Int32));
                criterea.Add(Expression.Sql("ForumId is null"));
// add grouping and sorting here
            return criterea.Future<Forum>();

What I need help with is adding in the correct grouping and ordering. It needs to be grouped by parentId (actual field name is ForumId, entity has no related property) and sorted by Sequence ASC.

There is no way to get a drag-and-drop UI in a web browser without either javascript or a RIA app of some sort.

I’d also argue that its reasonable in this day and age to expect JS to be turned on in almost all scenarios, especially in scenarios when people are doing sysadmin type work in a web system.

Somehow, I knew that somebody was going to reply with that. The problem is, if the current sysadmin doesn’t have JS enabled it won’t work. That’s reason enough for me not to use it.

However, I did finally get a nice little routine that creates a nested selectlist though:

public IEnumerable<SelectListItem> BuildForumSelectList(IEnumerable<Forum> entities)
IList<SelectListItem> list = new List<SelectListItem>();
ProcessForumSelectListItems(list, entities, 0);
return list;
private void ProcessForumSelectListItems(IList<SelectListItem> list, IEnumerable<Forum> entities, int level)
foreach (Forum entity in entities.OrderBy(x => x.Sequence))
ProcessForumSelectListItem(list, entity, level);
private void ProcessForumSelectListItem(IList<SelectListItem> list, Forum entity, int level)
SelectListItem item = new SelectListItem
Text = string.Format(“{0} {1}”, new string(‘-’, level * 2), entity.Title).Trim(),
Value = entity.Id.ToString()
ProcessForumSelectListItems(list, entity.Children, level + 1);

I would have specific view for dealing with moving things around, and make it easier with some kind of drag ‘n’ drop UI so the actual details are abstracted away

jquery.ui.draggable . . . .

This is why I lament the days when desktop apps were more popular than the internet. I have a hard time with the whole statelessness of thing. I’d have no clue how to implement a drop and drop thing with the web. I don’t really even understand ajax. I need a way of preparing what I need while still server side, so when I send it to the view, all it has to do is write it out.