2009-09-10 22 views
12

He estado buscando a través de una gran cantidad de tutoriales sobre jQuery arrastrable/desplegable, y tratando de aplicarlo a ASP.NET MVC, pero estoy realmente confundido.jQuery Arrastrable, Droppable, ASP.NET MVC

La mayoría de las muestras que sigo encontrando parecen bastante difíciles de entender al menos en lo que respecta a dónde están conectadas las cosas. Básicamente estoy tratando de tener un cuadro de destino (una 'lista') y una lista de unidades ('asistentes'). El objetivo es poder arrastrar cualquiera de las unidades al cuadro y se agregan a la lista en la base de datos.

¿Alguien sabe de algunas muestras más simples que puedan arrojar algo de luz sobre cómo usar esta parte de jQuery con ASP.NET MVC?

Por ejemplo, he estado buscando http://philderksen.com/2009/06/18/drag-and-drop-categorized-item-list-with-jquery-and-aspnet-mvc-part-1/ y es bastante limpio, pero simplemente no explica lo que necesito. No tiene mucho sentido y la mayor parte del código está bastante desparramado, y ni siquiera puedo rastrear dónde se están realizando ciertas llamadas para averiguar cómo están conectadas las cosas. (¿Cómo se jQuery llamando a las acciones del controlador, por ejemplo, para activar cuando se deja caer algo? ¿Cómo puedo obtener el ID del elemento que se arrastró para que pueda añadirlo a la meta?)


Aquí, hizo algunos cambios, me disculpo por la confusión. Todavía no está funcionando como trato de hacerlo. ¿Es posible hacer que no se disparen eventos si las cosas se reorganizan en su lista original, pero solo cuando se colocan en otra lista?

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

bien, estoy tratando de seguir las instrucciones de Phil, esto es lo que tengo hasta ahora ... espero que estoy aún en el camino correcto. Todo esto es muy nuevo para mi. Lo intento y lo intento, pero las cosas de 'actualización' nunca se disparan. . .

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

Y el 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> 

Y el repositorio ...

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

y el controlador

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

    } 
} 

Este método consigue que el estilo se parezca mucho más a cómo es su muestra ... pero realmente no funciona. No puede ser el id del elemento - pero haciendo los propios elementos se pueden ordenar no parece funcionar bien ....

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

El blog de referencia cerca del principio ahora se puede encontrar aquí: http://philderksen.com/2009/series-drag-and-drop-categorized-item-list-jquery-asp-net-mvc/ – Corin

Respuesta

9

Stacey - Veo que está haciendo referencia a mi blog y me encantaría ayudar.Estoy blogueando en un proyecto de arrastrar y soltar jquery asp.net mvc más grande, así que dividí mis publicaciones en partes y estoy a punto de llegar a la mitad (3 partes hasta ahora). Básicamente, la información que está buscando todavía no está completa, pero debería estar pronto.

Para empezar, depuro eventos usando la característica Firebug's logging. He aquí un ejemplo pruebas de eventos con el método sortable de 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)); 
    } 
}); 

Cuando un elemento se elimina mediante ordenable(), se dispara el evento de actualización. Utilizo el método de publicación AJAX de jQuery para enviar los datos a un controlador.

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

    } 
}); 

El numColumna variable está extrayendo el ID mediante el análisis del atributo id que se ha configurado en la vista. Vea part 3 en mi blog para ver cómo se procesa esto. Luego, tanto el número de columna como el conjunto de identificadores de sección (serializados en jquery) se publican en el controlador.

El método controlador reside en /Controllers/SectionController.cs y sólo acepta mensajes:

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

Hope que ayuda por ahora.

+0

Eso es bastante complicado. Estás tan lejos de mí que estoy bastante perdido. Pero veré si puedo mantener el ritmo, así que básicamente quiero almacenar la identificación de cada elemento en la vista. Entonces configura el elemento HTML id para col _ ### donde ## es el "id", y esto es lo que pasa a través de jQuery? – Ciel

+0

Por favor, perdóneme, Phil, he intentado con tu código y todavía estoy muy confundido. Soy un novato extremo con jQuery. No estoy tratando de cambiar el orden, básicamente estoy tratando de agregar elementos a una lista. ¿Sabes cuándo podrías tener más publicaciones así puedo seguir investigando? – Ciel

+0

Para responder a su primera pregunta, sí, estoy estableciendo el id de cada elemento en col _ ### con el código del lado del servidor. Luego, cuando jQuery dispara el evento de actualización, estoy agarrando ese atributo de identificación, analizando el id # de él, y pasando el id # al controlador usando jQuery's $ .post(). –

1

En jQuery UI lanzables, hay un evento "caída" que puede tomar una función para ejecutar. Por lo tanto, aquí es donde deberá cablear la llamada a la acción de su controlador para ejecutar algo en una "caída". También hay otros eventos en los que puede engancharse, como "fuera", "hover", etc. Consulte here en "Eventos" para obtener más detalles.

Aquí es un ejemplo en el enganche/llamar a la acción de su controlador a través de "soltar":

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

Zing! Se ha hecho. El problema era $ (this) .attr ("id"). Necesitaba ser $ (ui.item) .attr ("id"). Esto devuelve el elemento que se arrastra, en lugar del contenedor ordenable. Muchas gracias por toda su ayuda.

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