title: jQuery Draggable, Droppable, ASP.NET MVC
body: <p>I've been looking through a lot of tutorials on jQuery draggable/droppable, and trying to apply it to ASP.NET MVC, but I am really confused. </p>
  
  <p>Most of the samples I keep finding seem pretty difficult to understand at least where it pertains to where things are wired. I'm basically trying to have a targetable box (a 'roster') and a list of units ('attendees'). The goal is to be able to drag any of the units into the box, and they are added to the roster in the database.</p>
  
  <p>Does anyone know of some simpler samples that might shed some light on how to use this part of jQuery with ASP.NET MVC?</p>
  
  <p>For instance, I've been looking at <a href="http://philderksen.com/2009/06/18/drag-and-drop-categorized-item-list-with-jquery-and-aspnet-mvc-part-1/" rel="nofollow noreferrer">http://philderksen.com/2009/06/18/drag-and-drop-categorized-item-list-with-jquery-and-aspnet-mvc-part-1/</a> and it is pretty neat, but it just doesn't explain what I need. It doesn't make a lot of sense and most of the code is pretty strewn about, and I can't even trace where certain calls are being made to figure out how things are wired. (How is jQuery calling the Controller actions, for instance, to trigger when something is dropped? How do I get the ID of the item being dragged so I can add it to the target?)</p>
  
  <hr>
  
  <p>Here, I made some changes - I apologize for the confusion. It still isn't quite working how I'm trying to get it to. Is it possible to make it not fire events if things are re-arranged in their original list, but only when dropped onto another list?</p>
  
  <pre><code>&lt;%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage&lt;IEnumerable&lt;Draggable.Item&gt;&gt;" %&gt;
  
  &lt;asp:Content ContentPlaceHolderID="TitleContent" runat="server"&gt;
      Index
  &lt;/asp:Content&gt;
  &lt;asp:Content ContentPlaceHolderID="MainContent" runat="server"&gt;
      &lt;h2&gt;
          Index&lt;/h2&gt;
      &lt;div style="float: left; width: 250px;"&gt;
          &lt;ul class="itemBox"&gt;
              &lt;% foreach (var item in Model)
        { %&gt;
              &lt;% Html.RenderPartial("Item", item); %&gt;
              &lt;% } %&gt;
          &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div style="float: left; width: 250px;"&gt;
          &lt;ul class="itemBox"&gt;
              &lt;p&gt;
                  Drop here&lt;/p&gt;
          &lt;/ul&gt;
      &lt;/div&gt;
  &lt;/asp:Content&gt;
  &lt;asp:Content ContentPlaceHolderID="ScriptContent" runat="server"&gt;
      &lt;style type="text/css"&gt;
          #draggable {
              width: 100px;
              height: 100px;
              padding: 0.5em;
              float: left;
              margin: 10px 10px 10px 0;
          }
          #droppable {
              width: 150px;
              height: 150px;
              padding: 0.5em;
              float: left;
              margin: 10px;
          }
      &lt;/style&gt;
  
      &lt;script type="text/javascript"&gt;
          $(function() {
              $(".itemList").sortable({
                  connectWith: ".itemList",
                  containment: "document",
                  cursor: "move",
                  opacity: 0.8,
                  placeholder: "itemRowPlaceholder",
  
                  update: function(event, ui) {
                      //Extract column num from current div id
                      var colNum = $(this).attr("id").replace(/col_/, "");
                      $.post("/Home/UpdateSortOrder", { columnNum: colNum, sectionIdQueryString: $(this).sortable("serialize") });
                  }
              });
          });
      &lt;/script&gt;
  
  &lt;/asp:Content&gt;
  </code></pre>
  
  <hr>
  
  <p>Alright, I'm trying to follow Phil's instructions, this is what I have so far... I hope I am even on the right track. This is all very new to me. I'm trying and trying, but the 'update' stuff is never firing. . .</p>
  
  <pre><code>&lt;%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage&lt;IEnumerable&lt;Draggable.Item&gt;&gt;" %&gt;
  
  &lt;asp:Content ContentPlaceHolderID="TitleContent" runat="server"&gt;
      Index
  &lt;/asp:Content&gt;
  &lt;asp:Content ContentPlaceHolderID="MainContent" runat="server"&gt;
      &lt;h2&gt;
          Index&lt;/h2&gt;
      &lt;div style="float: left; width: 250px;"&gt;
          &lt;ul id="sortable" class="itemBox"&gt;
              &lt;% foreach (var item in Model)
        { %&gt;
              &lt;% Html.RenderPartial("Item", item); %&gt;
              &lt;% } %&gt;
          &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div id="droppable" class="ui-widget-header"&gt;
          &lt;p&gt;
              Drop here&lt;/p&gt;
      &lt;/div&gt;
  &lt;/asp:Content&gt;
  &lt;asp:Content ContentPlaceHolderID="ScriptContent" runat="server"&gt;
      &lt;style type="text/css"&gt;
          .draggable {
              width: 100px;
              height: 100px;
              padding: 0.5em;
              float: left;
              margin: 10px 10px 10px 0;
          }
          #droppable {
              width: 150px;
              height: 150px;
              padding: 0.5em;
              float: left;
              margin: 10px;
          }
      &lt;/style&gt;
  
      &lt;script type="text/javascript"&gt;
          $(function() {
              $("#sortable").sortable({
                  update: function(event, ui) {
                      //Extract column num from current div id
                      var colNum = $(this).attr("id").replace(/item_/, "");
  
                      $.post("UpdateSortOrder", { columnNum: colNum, sectionIdQueryString: $(this).sortable("serialize") });
                  }
              });
              $("#droppable").droppable({
                  drop: function(event, ui) {
                      $(this).find('p').html('Dropped!');
                      //Extract column num from current div id
                      var colNum = $(this).attr("id").replace(/item_/, "");
  
                      $.post("UpdateSortOrder", { columnNum: colNum, sectionIdQueryString: $(this).sortable("serialize") });
                  }
  
              });
          });
      &lt;/script&gt;
  
  &lt;/asp:Content&gt;
  </code></pre>
  
  <p><strong>And the Item.ascx</strong></p>
  
  <pre><code>&lt;%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl&lt;Draggable.Item&gt;" %&gt;
  
  &lt;li class="itemRow" id="item_&lt;%= Model.ItemId %&gt;"&gt;
      &lt;p&gt;Drag me to my target&lt;/p&gt;
  &lt;/li&gt;
  </code></pre>
  
  <p><strong>And the repository...</strong></p>
  
  <pre><code>using System;
  using System.Linq;
  
  namespace Draggable
  {
      public partial class ItemRepository
      {
          DatabaseDataContext database = new DatabaseDataContext();
  
          public IQueryable&lt;Item&gt; GetItems()
          {
              var items = from i in database.Items
                          select i;
              return items;
          }
      }
  }
  </code></pre>
  
  <p><strong>And the controller</strong></p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.Linq;
  using System.Web;
  using System.Web.Mvc;
  using System.Web.Mvc.Ajax;
  
  namespace Draggable.Controllers
  {
      public class HomeController : Controller
      {
          //
          // GET: /Index/
  
          public ActionResult Index()
          {
              ItemRepository repository = new ItemRepository();
  
              return View("Index", repository.GetItems());
          }
  
          public ActionResult Item()
          {
              return View();
          }
  
      }
  }
  </code></pre>
  
  <hr>
  
  <p>This method gets the styling a lot closer to how your sample is ...but it really doesn't work. It doesn't get the id of the element - but making the elements themselves sortable doesn't seem to work either....</p>
  
  <pre><code>&lt;%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage&lt;IEnumerable&lt;Draggable.Item&gt;&gt;" %&gt;
  
  &lt;asp:Content ContentPlaceHolderID="TitleContent" runat="server"&gt;
      Index
  &lt;/asp:Content&gt;
  &lt;asp:Content ContentPlaceHolderID="MainContent" runat="server"&gt;
      &lt;h2&gt;
          Index&lt;/h2&gt;
      &lt;div class="itemBox"&gt;
          &lt;ul class="itemList"&gt;
              &lt;% foreach (var item in Model)
        { %&gt;
              &lt;% Html.RenderPartial("Item", item); %&gt;
              &lt;% } %&gt;
          &lt;/ul&gt;
      &lt;/div&gt;
      &lt;div class="itemBox"&gt;
          &lt;ul class="itemList"&gt;
              &lt;p&gt;
                  Drop here&lt;/p&gt;
          &lt;/ul&gt;
      &lt;/div&gt;
  &lt;/asp:Content&gt;
  &lt;asp:Content ContentPlaceHolderID="ScriptContent" runat="server"&gt;
      &lt;script type="text/javascript"&gt;
          $(function() {
              $(".itemList").sortable({
                  connectWith: ".itemList",
                  containment: "document",
                  cursor: "move",
                  opacity: 0.8,
                  placeholder: "itemRowPlaceholder",
  
                  update: function(event, ui) {
                      //Extract column num from current div id
                      var colNum = $(this).attr("id").replace(/col_/, "");
                      alert(colNum);
                      $.post("/Home/UpdateSortOrder", { columnNum: colNum, sectionIdQueryString: $(this).sortable("serialize") });
                  }
              });
          });
      &lt;/script&gt;
  
  &lt;/asp:Content&gt;
  </code></pre>