Simon Miller Team : Web Development Tags : Web Development jQuery MVC

Sorting with Nestable and Bootstrap MVC

Simon Miller Team : Web Development Tags : Web Development jQuery MVC

Whilst working on a custom admin intranet for a project, I discovered a section in the scope where I had to sort rows via drag and drop that would then update the database. We’ve all had to do something like this in the past, but this combination of jQuery plugin, Bootstrap MVC theme and .NET makes short work of it (about an hour all up).

The plugin supports hierarchy, but for my purposes this was not required. I will show you how to sort and commit to the database a linear list. This guide assumes you are using the Bootstrap Beyond Admin theme which includes styles for the plugin, though I am sure it would be easy to adapt to other Bootstrap themes.

Firstly, add the Nestable jQuery plugin to your website (this is already done for you in the Beyond Admin theme).

In your HTML, set up the structure of the list you wish to sort. Below I have a model called Lesson which contains many Slide models. A slide consist of an Id (int), SortOrder (int) and Name (string). The controller loads the Lesson and Slides, ordering by SortOrder ascending.

<div class="dd shadowed">
    <ol class="dd-list">
    @foreach (var slide in lesson.Slides)
    {
        <li class="dd-item bordered-blue" data-id="@slide.Id" data-SortOrder="@slide.SortOrder">
            <div class="dd-handle"> @slide.Name
            </div>
        </li>
    }
    </ol>
</div>

Instantiate the Nestable plugin:

<script src="/scripts/nestable/jquery.nestable.min.js"></script>
<script type="text/javascript">
    $('.dd').nestable();
</script>

You should now have a working list that sorts your items when you drag them – but you still need to commit these changes to the database. Add a button Update Sort Order below the sortable list, apply a class “updateSort” and create the following jQuery click event:

$(".updateSort").click(function (e) {
    var json = $('.dd').nestable('serialize');
    var ids = $(json).map(function () {
        return this.id;
    }).get();
    $.ajax({  
        type: 'PUT',
        url: '@Url.Action("UpdateOrder")',
        data: { ids: ids }
    })
    .done(function (result) {
        alert(result.success);
    });
});

This function uses the Nestable’s serialize method to concatenate all the item ID values in their new order into a list that can be passed to an MVC controller method. That method is as simple as this:

[HttpPut]
public async Task<ActionResult> UpdateOrder(IList<int> ids)
{
    try
    {
        await _repository.UpdateOrder(ids);
        return Json(new { @success = true });
    }
    catch (Exception ex)
    {
        return Json(new { @success = false });
    }
}

And the UpdateOrder() repository method:

public async Task UpdateSorting(List<int> ids)
{
    for (int i = 0; i < ids.Count(); i++)
    {
        var id = ids[i];
        var slide = await Context.Slides.FirstOrDefaultAsync(e => e.Id == id);
        slide.SortOrder = i;
        await Context.SaveChangesAsync();
    }
}

The controller method merely handles communication between view and database repository. The repository method loops through the IDs – keeping their new order – and updates the SortOrder value incrementally starting from 0.

If the initial controller method to populate the list returns its results in this SortOrder then we now have a complete system for reordering rows and updating the database.