2009-09-10 16 views
12

Przeglądałem wiele tutoriali na temat jQuery draggable/droppable i próbowałem zastosować go do ASP.NET MVC, ale jestem bardzo zdezorientowany.jQuery Draggable, Droppable, ASP.NET MVC

Większość próbek, które znajduję, wydaje się dość trudna do zrozumienia, przynajmniej jeśli chodzi o to, gdzie rzeczy są podłączone. Zasadniczo próbuję mieć pole do wybrania ("spis") i listę jednostek ("uczestników"). Celem jest możliwość przeciągnięcia dowolnej jednostki do pudełka i są one dodawane do planu w bazie danych.

Czy ktoś wie o prostszych próbkach, które mogą rzucić nieco światła na sposób korzystania z tej części jQuery z ASP.NET MVC?

Na przykład, patrzyłem na http://philderksen.com/2009/06/18/drag-and-drop-categorized-item-list-with-jquery-and-aspnet-mvc-part-1/ i jest całkiem schludny, ale po prostu nie wyjaśnia, czego potrzebuję. To nie ma większego sensu i większość kodu jest bardzo porozrzucana, a ja nie mogę nawet śledzić, gdzie są wykonywane pewne połączenia, aby dowiedzieć się, jak rzeczy są połączone. (Jak jQuery wywołanie działania sterownika, na przykład, aby wywołać, gdy coś jest odrzucany? Jak uzyskać identyfikator elementu przeciągany więc mogę dodać go do celu?)


Tutaj ja wprowadzono pewne zmiany - przepraszam za zamieszanie. Nadal nie działa tak, jak próbuję to osiągnąć. Czy jest możliwe, aby nie były to zdarzenia pożaru, jeśli rzeczy zostały ponownie ustawione na ich oryginalnej liście, ale tylko wtedy, gdy zostały przeniesione na inną listę?

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Draggable.Item>>" %> 

<asp:Content ContentPlaceHolderID="TitleContent" runat="server"> 
    Index 
</asp:Content> 
<asp:Content ContentPlaceHolderID="MainContent" runat="server"> 
    <h2> 
     Index</h2> 
    <div style="float: left; width: 250px;"> 
     <ul class="itemBox"> 
      <% foreach (var item in Model) 
     { %> 
      <% Html.RenderPartial("Item", item); %> 
      <% } %> 
     </ul> 
    </div> 
    <div style="float: left; width: 250px;"> 
     <ul class="itemBox"> 
      <p> 
       Drop here</p> 
     </ul> 
    </div> 
</asp:Content> 
<asp:Content ContentPlaceHolderID="ScriptContent" runat="server"> 
    <style type="text/css"> 
     #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; 
     } 
    </style> 

    <script type="text/javascript"> 
     $(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") }); 
       } 
      }); 
     }); 
    </script> 

</asp:Content> 

porządku, staram się postępować zgodnie z instrukcjami Phila, to co mam tak daleko ... Mam nadzieję, że jeszcze jestem na dobrej drodze. To wszystko jest dla mnie bardzo nowe. Próbuję i próbuję, ale rzeczy z "aktualizacji" nigdy nie strzelają. . .

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Draggable.Item>>" %> 

<asp:Content ContentPlaceHolderID="TitleContent" runat="server"> 
    Index 
</asp:Content> 
<asp:Content ContentPlaceHolderID="MainContent" runat="server"> 
    <h2> 
     Index</h2> 
    <div style="float: left; width: 250px;"> 
     <ul id="sortable" class="itemBox"> 
      <% foreach (var item in Model) 
     { %> 
      <% Html.RenderPartial("Item", item); %> 
      <% } %> 
     </ul> 
    </div> 
    <div id="droppable" class="ui-widget-header"> 
     <p> 
      Drop here</p> 
    </div> 
</asp:Content> 
<asp:Content ContentPlaceHolderID="ScriptContent" runat="server"> 
    <style type="text/css"> 
     .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; 
     } 
    </style> 

    <script type="text/javascript"> 
     $(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") }); 
       } 

      }); 
     }); 
    </script> 

</asp:Content> 

A Item.ascx

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Draggable.Item>" %> 

<li class="itemRow" id="item_<%= Model.ItemId %>"> 
    <p>Drag me to my target</p> 
</li> 

I repozytorium ...

using System; 
using System.Linq; 

namespace Draggable 
{ 
    public partial class ItemRepository 
    { 
     DatabaseDataContext database = new DatabaseDataContext(); 

     public IQueryable<Item> GetItems() 
     { 
      var items = from i in database.Items 
         select i; 
      return items; 
     } 
    } 
} 

a kontroler

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(); 
     } 

    } 
} 

Ta metoda sprawia, że ​​stylizacja jest znacznie bliższa Twojej próbce ... ale tak naprawdę nie działa. To nie uzyskać identyfikator elementu - ale co same elementy sortowane przez nie wydają się działać albo ....

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Draggable.Item>>" %> 

<asp:Content ContentPlaceHolderID="TitleContent" runat="server"> 
    Index 
</asp:Content> 
<asp:Content ContentPlaceHolderID="MainContent" runat="server"> 
    <h2> 
     Index</h2> 
    <div class="itemBox"> 
     <ul class="itemList"> 
      <% foreach (var item in Model) 
     { %> 
      <% Html.RenderPartial("Item", item); %> 
      <% } %> 
     </ul> 
    </div> 
    <div class="itemBox"> 
     <ul class="itemList"> 
      <p> 
       Drop here</p> 
     </ul> 
    </div> 
</asp:Content> 
<asp:Content ContentPlaceHolderID="ScriptContent" runat="server"> 
    <script type="text/javascript"> 
     $(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") }); 
       } 
      }); 
     }); 
    </script> 

</asp:Content> 
+0

Blog odwołuje blisko początku można teraz znaleźć tutaj: http://philderksen.com/2009/series-drag-and-drop-categorized-item-list-jquery-asp-net-mvc/ – Corin

Odpowiedz

9

Stacey - Widzę, że odwołanie mojego bloga i chciałbym pomóc.Bloguję na większym projekcie jquery asp.net mvc drag and drop, więc podzielę moje posty na części i jestem tylko w połowie drogi (3 części do tej pory). Zasadniczo informacje, których szukasz, nie są jeszcze dostępne, ale powinny wkrótce.

Na początek debuguję zdarzenia przy użyciu funkcji Firebug's logging. Oto przykład testowania wydarzenia z jQuery UI sortable metodą jest():

$("#mylist").sortable(
{ 
    ... 
    start: function(event, ui) 
    { 
     console.log("-- start fired --"); 
     console.log($(ui.item)); 
    }, 

    update: function(event, ui) 
    { 
     console.log("-- update fired --"); 
     console.log($(ui.item)); 
    }, 

    deactivate: function(event, ui) 
    { 
     console.log("-- deactivate fired --"); 
     console.log($(ui.item)); 
    } 
}); 

Jeżeli pozycja jest usuwana przy użyciu sortable(), pożary zdarzenie aktualizacji. Używam metody posta AJAX jQuery do wysyłania danych do kontrolera.

$("#mylist").sortable(
{ 
    ... 
    update: function(event, ui) 
    { 
     //Extract column num from current div id 
     var colNum = $(this).attr("id").replace(/col_/, ""); 

     $.post("/Section/UpdateSortOrder", 
      { columnNum: colNum, sectionIdQueryString: $(this).sortable("serialize") }); 

    } 
}); 

Zmienna colNum wyodrębnia identyfikator, analizując atrybut id ustawiony w widoku. Zobacz part 3 na moim blogu, aby dowiedzieć się, jak to się dzieje. Następnie zarówno numer kolumny, jak i zestaw identyfikatorów sekcji (serializowane w jquery) są wysyłane do kontrolera.

Metoda kontroler znajduje się w /Controllers/SectionController.cs i akceptuje tylko posty:

private SectionRepository secRepo = new SectionRepository(); 

    [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult UpdateSortOrder(int columnNum, string sectionIdQueryString) 
    { 
     string[] separator = new string[2] { "section[]=", "&" }; 
     string[] sectionIdArray = sectionIdQueryString.Split(separator, StringSplitOptions.RemoveEmptyEntries); 

     secRepo.UpdateSortOrder(columnNum, sectionIdArray); 
     secRepo.Save(); 

     return Content("Success"); 
    } 

nadzieję, że pomoże teraz.

+0

To całkiem garść. Jesteś tak daleko przede mną, że jestem całkiem zgubiony. Ale zobaczę, czy uda mi się nadążyć - więc zasadniczo chcę przechowywać identyfikator każdego elementu w widoku? Ustawiasz więc element id HTML na col _ ### gdzie ## jest "id", i to jest to, co przechodzisz przez jQuery? – Ciel

+0

Wybacz mi, Phil, wypróbowałem twój kod i nadal jestem bardzo zdezorientowany. Jestem ekstremalnym debiutantem z jQuery. Naprawdę nie próbuję zmienić kolejności, próbuję zasadniczo dodać elementy do listy. Czy wiesz, kiedy możesz opublikować więcej tego artykułu, aby móc go dalej badać? – Ciel

+0

Aby odpowiedzieć na twoje pierwsze pytanie, tak ustawiam id każdego elementu na col _ ### z kodem po stronie serwera. Następnie, gdy jQuery odpala wydarzenie aktualizacji, przechwytywam ten atrybut id, analizując identyfikator # od niego, a następnie przekazując identyfikator # do kontrolera za pomocą $ .post() jQuery. –

1

W jQuery UI droppable istnieje „drop” wydarzenie, które może trwać funkcja do wykonania. To jest miejsce, w którym będziesz musiał połączyć się z działaniem kontrolera, aby wykonać coś na "drop". Są też inne zdarzenia, do których możesz się podłączyć, np. "Na zewnątrz", "najeżdżaj" itp. Więcej szczegółów znajdziesz w części "Zdarzenia" pod numerem here.

Oto przykład w zahaczanie/nazywając działania kontrolera za pośrednictwem „drop”:

$('#mylist').droppable({ 
    drop: function(event, ui) { 
     var newItem = ui.droppable; 
     var url = <% =Url.Action("Append", "MyController") %>; 
     $.post(url, { newItemId: newItem[0].id }); 
    } 
}); 
0

Zing! Zostało zrobione. Problem polegał na $ (this) .attr ("id"). Musiał to być $ (ui.item) .attr ("id"). Zwraca element przeciągany, a nie sortowalny kontener. Dziękuje Ci bardzo za całą twoją pomoc.

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Draggable.Item>>" %> 

<asp:Content ContentPlaceHolderID="TitleContent" runat="server"> 
    Index 
</asp:Content> 
<asp:Content ContentPlaceHolderID="MainContent" runat="server"> 
    <ul id="sortable1" class="connectedSortable"> 
     <% foreach (var item in Model) 
    { %> 
     <% Html.RenderPartial("Item", item); %> 
     <% } %> 
    </ul> 
    <ul id="sortable2" class="connectedSortable"> 
    </ul> 
</asp:Content> 
<asp:Content ContentPlaceHolderID="ScriptContent" runat="server"> 
    <style type="text/css"> 
     #sortable1, #sortable2 { 
      list-style-type: none; 
      margin: 0; 
      padding: 0; 
      float: left; 
      margin-right: 10px; 
     } 
     #sortable2 { 
      height: 400px; 
      width: 140px; 
      background: #ccc; 
     } 
     #sortable1 li, #sortable2 li { 
      margin: 0 5px 5px 5px; 
      padding: 5px; 
      font-size: 1.2em; 
      width: 120px; 
     } 
    </style> 

    <script type="text/javascript"> 
     $(function() { 
      $("#sortable1").sortable({ 
       connectWith: '.connectedSortable' 
      }).disableSelection(); 
      $("#sortable2").sortable({ 
       connectWith: '.connectedSortable', 
       receive: function(event, ui) { 
        var colNum = $(ui.item).attr("id").replace(/col_/, ""); 
        $.post("/Home/UpdateSortOrder", { columnNum: colNum, sectionIdQueryString: $(this).sortable("serialize") }); 
       } 
      }).disableSelection(); 
     }); 
    </script> 
</asp:Content>