JQuery Draggable, Droppable, ASP.NET MVC
Я просматривал множество учебников по jQuery draggable/droppable и пытаюсь применить его к ASP.NET MVC, но я действительно смущен.
Большинство образцов, которые я нахожу, кажутся довольно трудными для понимания, по крайней мере, там, где это относится к тому, где вещи связаны. Я в основном пытаюсь иметь целевую коробку ( "список" ) и список единиц ( "участников" ). Цель состоит в том, чтобы иметь возможность перетаскивать любой из блоков в поле, и они добавляются в список в базе данных.
Кто-нибудь знает о некоторых более простых образцах, которые могут пролить свет на то, как использовать эту часть jQuery с ASP.NET MVC?
Например, я смотрел http://philderksen.com/2009/06/18/drag-and-drop-categorized-item-list-with-jquery-and-aspnet-mvc-part-1/, и это довольно аккуратно, но это просто не объясняет, что я необходимость. Это не имеет большого смысла, и большая часть кода довольно разбросана, и я даже не могу отслеживать, где сделаны определенные вызовы, чтобы выяснить, как вещи связаны. (Как jQuery вызывает действия Controller, например, для запуска, когда что-то отбрасывается? Как получить идентификатор перетаскиваемого элемента, чтобы я мог добавить его в цель?)
Здесь я внес некоторые изменения - я извиняюсь за путаницу. Это все еще не совсем работает, как я пытаюсь это сделать. Возможно ли, что это не события пожара, если вещи переустановлены в их исходном списке, но только когда они попадают в другой список?
<%@ 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>
Хорошо, я пытаюсь следовать инструкциям Фила, это то, что у меня есть до сих пор... Надеюсь, я даже на правильном пути. Это все очень ново для меня. Я пытаюсь и стараюсь, но материал "обновления" никогда не срабатывает.,.
<%@ 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>
И 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>
И репозиторий...
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;
}
}
}
И контроллер
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();
}
}
}
Этот метод намного упрощает стиль, чем ваш образец... но он действительно не работает. Он не получает идентификатор элемента - но создание самих элементов сортировки, похоже, не работает.
<%@ 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>
Ответы
Ответ 1
Стейси - Я вижу, что ты ссылаешься на мой блог и хотел бы помочь. Я занимаюсь ведением блога на более крупном проекте asp.net mvc drag and drop, поэтому я разделяю свои сообщения на части, и я всего лишь на полпути (до 3 частей). В принципе, информация, которую вы ищете, еще не все, но должна быть скоро.
Для начала я отлаживаю события, используя Firebug logging. Здесь пример тестирования событий с помощью метода сортировки jQuery UI sortable():
$("#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));
}
});
Когда элемент отбрасывается с помощью sortable(), он запускает событие обновления. Я использую метод jQuery AJAX post для отправки данных контроллеру.
$("#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") });
}
});
Переменная colNum извлекает идентификатор, анализируя атрибут id, который задан в представлении. См. часть 3 в моем блоге, как это делается. Затем и номер столбца, и идентификатор секции (сериализованный в jquery) отправляются в контроллер.
Метод контроллера находится в /Controllers/SectionController.cs и принимает только сообщения:
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");
}
Надеюсь, что это поможет.
Ответ 2
В jQuery UI droppable есть событие "drop" , которое может выполнять функцию для выполнения. Таким образом, вам понадобится связать вызов с действием вашего контроллера, чтобы выполнить что-то на "drop" . Существуют и другие события, которые вы можете подключить, например, "выходить", "навести" и т.д. См. здесь в разделе "События" для более подробно.
Вот пример подключения/вызова действия вашего контроллера через "drop" :
$('#mylist').droppable({
drop: function(event, ui) {
var newItem = ui.droppable;
var url = <% =Url.Action("Append", "MyController") %>;
$.post(url, { newItemId: newItem[0].id });
}
});
Ответ 3
Zing! Это было сделано. Проблема была $(this).attr( "id" ). Это должно быть $(ui.item).attr( "id" ). Это возвращает элемент, который перетаскивается, а не сортируемый контейнер. Большое вам спасибо за вашу помощь.
<%@ 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>