2009-09-10 34 views
12

Tôi đã xem qua rất nhiều hướng dẫn về jQuery có thể kéo/có thể tháo rời và cố gắng áp dụng nó cho ASP.NET MVC, nhưng tôi thực sự bối rối.jQuery Draggable, Droppable, ASP.NET MVC

Hầu hết các mẫu tôi tiếp tục tìm kiếm có vẻ khá khó hiểu ít nhất là nơi nó liên quan đến nơi mọi thứ được kết nối. Tôi về cơ bản đang cố gắng để có một hộp có thể nhắm mục tiêu (một 'danh sách') và một danh sách các đơn vị ('người tham dự'). Mục đích là để có thể kéo bất kỳ đơn vị nào vào hộp và chúng được thêm vào danh sách trong cơ sở dữ liệu.

Có ai biết một số mẫu đơn giản hơn có thể làm sáng tỏ một số cách sử dụng phần này của jQuery với ASP.NET MVC không?

Ví dụ, tôi đã xem http://philderksen.com/2009/06/18/drag-and-drop-categorized-item-list-with-jquery-and-aspnet-mvc-part-1/ và nó khá gọn gàng, nhưng nó không giải thích được những gì tôi cần. Nó không tạo ra nhiều ý nghĩa và hầu hết đoạn mã đều khá vất vả, và tôi thậm chí không thể theo dõi được một số cuộc gọi đang được thực hiện để tìm ra cách mọi thứ được kết nối. (Như thế nào jQuery gọi các hành động điều khiển, ví dụ, để kích hoạt khi một cái gì đó bị rơi? Làm thế nào để có được ID của mặt hàng đó bị kéo vì vậy tôi có thể thêm nó vào mục tiêu?)


Ở đây, tôi đã thực hiện một số thay đổi - tôi xin lỗi vì sự nhầm lẫn. Nó vẫn không hoàn toàn làm việc như thế nào tôi đang cố gắng để làm cho nó. Có thể làm cho nó không cháy sự kiện nếu mọi thứ được sắp xếp lại trong danh sách ban đầu của họ, nhưng chỉ khi rơi vào một danh sách khác?

<%@ 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> 

Được rồi, tôi đang cố gắng để làm theo hướng dẫn Phil, đây là những gì tôi có cho đến nay ... Tôi hy vọng tôi thậm chí đi đúng hướng. Điều này hoàn toàn mới đối với tôi. Tôi đang cố gắng và cố gắng, nhưng công cụ 'cập nhật' không bao giờ được kích hoạt. . .

<%@ 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> 

Và 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> 

Và kho ...

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

Và bộ điều khiển

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

    } 
} 

Phương pháp này nhận được kiểu dáng gần gũi hơn với cách mẫu của bạn ... nhưng nó thực sự không hoạt động. Nó không nhận được id của phần tử - nhưng làm cho các yếu tố tự phân loại dường như không hoạt động ...

<%@ 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 được tham chiếu gần đầu có thể được tìm thấy tại đây: http://philderksen.com/2009/series-drag-and-drop-categorized-item-list-jquery-asp-net-mvc/ – Corin

Trả lời

9

Stacey - Tôi thấy bạn đang tham khảo blog của tôi và rất thích giúp đỡ.Tôi viết blog trên một dự án kéo và thả jquery asp.net mvc jquery lớn hơn vì vậy tôi chia bài viết của tôi thành các phần và tôi chỉ khoảng nửa chừng (3 phần cho đến nay). Về cơ bản, thông tin bạn đang tìm kiếm không phải là tất cả ở đó, nhưng sẽ sớm.

Để bắt đầu, tôi gỡ lỗi sự kiện bằng cách sử dụng tính năng Firebug's logging. Dưới đây là ví dụ về các sự kiện thử nghiệm với phương thức sắp xếp() của jQuery UI:

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

Khi một mục bị xóa bằng cách sắp xếp(), nó sẽ kích hoạt sự kiện cập nhật. Tôi sử dụng phương thức AJAX của jQuery để gửi dữ liệu đến một bộ điều khiển.

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

    } 
}); 

Biến colNum đang trích xuất id bằng cách phân tích thuộc tính id được đặt trong chế độ xem. Xem part 3 trên blog của tôi để biết cách hiển thị. Sau đó, cả số cột và tập hợp các phần id (được tuần tự hóa trong jquery) được đăng lên bộ điều khiển.

Phương pháp điều khiển nằm trong /Controllers/SectionController.cs và chỉ chấp nhận bài viết:

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

Hy vọng rằng sẽ giúp cho bây giờ.

+0

Đó là một số ít. Bạn đang ở phía trước của tôi rằng tôi khá bị mất. Nhưng tôi sẽ thấy nếu tôi có thể theo kịp - vì vậy về cơ bản tôi muốn lưu trữ ID của từng mục trong Chế độ xem? Vì vậy, bạn đặt phần tử id HTML thành col _ ### trong đó ## là "id", và đây là những gì bạn vượt qua jQuery? – Ciel

+0

Hãy tha thứ cho tôi, Phil, tôi đã thử mã của bạn và tôi vẫn còn rất bối rối. Tôi là một tân binh cực đoan với jQuery. Tôi không thực sự cố gắng thay đổi thứ tự, tôi đang cố gắng thêm các mục vào danh sách cơ bản. Bạn có biết khi nào bạn có thể xuất bản nhiều hơn để tôi có thể tiếp tục nghiên cứu nó không? – Ciel

+0

Để trả lời câu hỏi đầu tiên của bạn, có, tôi đang đặt id của mỗi phần tử thành col _ ### với mã phía máy chủ. Sau đó, khi jQuery kích hoạt sự kiện cập nhật, tôi lấy thuộc tính id đó, phân tích cú pháp id # từ nó, sau đó chuyển id # tới controller bằng cách sử dụng $ .post() của jQuery. –

1

01 Trong giao diện jQuery có thể phân hủy, có sự kiện "thả" có thể mất một hàm để thực hiện. Vì vậy, đây là nơi bạn sẽ cần phải dây cuộc gọi đến hành động của bộ điều khiển của bạn để thực hiện một cái gì đó trên một "thả". Có những sự kiện khác mà bạn có thể móc nối, chẳng hạn như "ra", "di chuột", v.v. Xem here trong "Sự kiện" để biết thêm chi tiết.

Dưới đây là một ví dụ trong hooking/gọi hành động của bộ điều khiển của bạn thông qua "thả":

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

Zing! Đã hoàn thành. Vấn đề là $ (this) .attr ("id"). Nó cần phải là $ (ui.item) .attr ("id"). Điều này trả về phần tử đang được kéo, chứ không phải là vùng chứa có thể sắp xếp. Cảm ơn bạn rất nhiều vì tất cả sự giúp đỡ của bạn.

<%@ 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> 
Các vấn đề liên quan