¿Cómo usar Drag and Drop en elementos de ASP WebForm y guardar las posiciones?

ASP.NET WebFom si bien tiene herramientas poderosas que facilitan mucho la programación en comparación con otros métodos, también presenta problemas de lógica que solo podemos superar después de mucho esfuerzo e intentos constantes, uno de esos problemas y que vuelve complicado y poco intuitivo el modelo de trabajo es usar el Drag and Drop en los controles.

Si tu inquietud es:

  • ¿Cómo hacer Drag and Drop en controles ASP.NET Webform?
  • ¿Cómo hacer Drag and Drop en controles Listbox?
  • ¿Cómo hacer Drag and Drop en controles Listas?
  • Acá tratare de explicarte de la manera mas fácil, como hacerlo.

Construcción del objeto y uso de JQUERY

Primero, no se olviden de agregar las referencias a JQUERY y JQUERY-UI

<link href="<%= ResolveClientUrl("../js/jquery-ui-1.12.1/jquery-ui.css")%>" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script src="<%= ResolveClientUrl("../js/jquery-ui-1.12.1/jquery-ui.min.js")%>" type="text/javascript"></script>

Utilizamos la función ResolveClientUrl para corregir cualquier problema que tengamos del lado del cliente con las rutas de cada página.

Ahora, para este ejemplo crearemos una lista desordenada (Etiqueta UL) utilizando el control “Repeater”. El código nos quedaría de la siguiente forma:

                <asp:Repeater ID="rptList" runat="server">
                    <HeaderTemplate>
                        <ul class=" sortable1 connectedSortable">
                    </HeaderTemplate>
                    <ItemTemplate>
                        <li>
                            <%# Eval("NOMBRE")%>
                            <input id="c-<%# Eval("CODIGO")%>" value="<%# Eval("CODIGO")%>" type="hidden" />
                        </li>
                    </ItemTemplate>
                    <FooterTemplate>
                        </ul>
                    </FooterTemplate>
                </asp:Repeater>

                <ul class="sortable2 connectedSortable">
                    <li class="sortable-tiulo ui-state-disabled">-- Arrastre aquí para ordenar sus rutas --</li>
                </ul>

En el código anterior utilizamos el control REPEATER para ser llenado desde la base de datos y mostrar una lista donde se visualizara el nombre de un cliente o producto, adicionalmente ocultamos el código de ese registro a través de un Input de tipo Hiddden.

Es importante tomar en cuenta que estamos usando etiquetas HTML y no ASP, además las clases que usamos en la etiqueta UL son de suma importancia.

  1. Sortable1: Es una clase que usa el JQUERY para determinar que el control podría usar el Drag and Drop (Arrastrar y soltar)
  • ConnectedSortable: Indica que este elemento podrá combinarse con otros elementos de su mismo tipo e intercambiar datos entre si. Es decir, si tengo dos listas, puedo arrastrar y soltar entre ambas listas.

La segunda lista (Etiqueta UL), la usaremos únicamente para transferir elementos de una lista a otra. Podemos notar que agregamos un item por defecto para mostrar un mensaje al usuario.

¿Cómo llenamos el control Repeater para hacer el Drag and Drop?

El llenado del control es sumamente fácil, es igual que el llenado de un Grid o Lisbtox, dejo el código a continuación:

    Private Sub Load_Clientes_Activos()
        Dim cnn As String = “CADENA DE CONEXIÓN CON TU BASE DE DATOS”
        Dim dbCon As New System.Data.OleDb.OleDbConnection(cnn)
        Try
            If dbCon.State = ConnectionState.Closed Then
                dbCon.Open()
            End If

            Dim sql As String = String.Empty
            sql = "SELECT  CODIGO , NOMBRE  FROM CLIENTES"

            Dim daSrc As New System.Data.OleDb.OleDbDataAdapter(sql, dbCon)
            Dim dt As New DataTable("DT")
            daSrc.Fill(dt)

            Me.rptList.DataSource = dt
            Me.rptList.DataBind()

            dt.Dispose()

        Catch ex As Exception
            Me.ltMensaje.Text = "Ocurrió un error."

        End Try
    End Sub

¿Cómo hago funcionar el Drag and Drop entre ambas listas?

Es muy fácil, solo debemos agregar el siguiente código JavaScript.

            $(".sortable1, .sortable2").sortable({
                placeholder: "ui-state-highlight",
                connectWith: ".connectedSortable",
                items: "li:not(.ui-state-disabled)"
            }).disableSelection();

Tan sencillo como esto, ya solo agregando este código en nuestro Javascript tendremos la funcionalidad de arrastrar y soltar (Drag and Drop) elementos de una lista a otra o entre si. Entonces lo que necesitamos es:

  1. Agregar referencias a JQUERY y JQUERY-UI
  2. Agregar dos conjuntos de elementos. Para nuestro ejemplo usamos listas UL pero podrían ser Listbox, Gridview, Etc.
    1. En nuestro ejemplo usamos un control repeater que llenamos desde la base de datos para generar una lista dinámica.
  3. Incorporar las clases sortable a cada lista respectivamente.

¿Ahora que puedo hacer con mi lista ordenada usando Drag and Drop?

Bien, podemos ordenar de nuestra lista arrastrando y soltando, ¡eso es genial!, pero ¿Ahora qué?, si no podemos hacer algo con ello entonces es innecesario, por eso imaginemos este escenario:

Tenemos un listado de CLIENTES  a los cuales se les entregan productos dependiendo de un orden específico, en nuestra aplicación podemos ordenarlos pero necesitamos grabar ese orden en la base de datos, si lo hacemos usando control LISTBOX de ASP, al guardar nos daremos cuenta que perdemos el orden, esto es por el VIEWSTATE del control un tema aparte que veremos en otra ocasión. Pero entonces, ¿como guardamos el orden de nuestro control cuando usamos Drag and Drop?

Para solucionar el problema anterior, lo que haremos será usar un WebMethod es decir, crearemos un servicio web ya sea remoto o en nuestra aplicación; para mas información visita nuestra publicación anterior:

Una vez tenemos creado nuestro archivo principal del servicio web, adicionaremos una referencia a nuestro proyecto, adicionaremos el Newtonsoft que nos permitira el manejo de datos JSON mas fácilmente, para ello hacemos lo siguiente:

Herramientas –> Administrador de paquetes NuGet –> Administrador de paquetes NuGet para la solución…

Buscamos Newtonsoft.Jason y lo agregamos a nuestro proyecto

Una vez estemos en nuestro servicio web, agregamos la referencia:

Imports Newtonsoft.Json
Imports System.Web.Services.Protocols.SoapHttpClientProtocol

Ahora para capturar la lista según el orden definido desde HTML usando Drag and Drop, usamos el siguiente método desde nuestro servicio web

    <DataContract()>
    Public Class Mensaje
        <DataMember>
        Public Property msg As String
    End Class

    <WebMethod()> _
    Public Function sendRutas(ruta As String, clientes As String) As String
        Try
            '' VARIABLE QUE SERA USADA PARA ENVIAR EL MENSAJE AL NAVEGADOR
            Dim mostrar As String = String.Empty

            If ruta = String.Empty Then
                mostrar = "El proceso no puede continuar. No se encontró una ruta que procesar."
            End If

            Dim dt As DataTable = JsonConvert.DeserializeObject(Of DataTable)(clientes)

            If Not dt.Rows.Count > 0 And mostrar.Trim = String.Empty Then
                mostrar = "El proceso no puede continuar. No existen clientes que procesar en la ruta."
            End If

            ' INICIA: CONSTRUCCIÓN DEL QUERY ****************
            If mostrar = String.Empty Then
                mostrar = "NOMBRE DE RUTA: " & ruta
                mostrar &= " NO. DE CLIENTES: " & dt.Rows.Count

                For i As Integer = 0 To dt.Rows.Count - 1
                     mostrar &= " INDEX: " & (i + 1) & " - CODIGO: " & dt.Rows(i).Item(0).ToString.Trim
                 Next i
            End If
            ' TERMINA: CONSTRUCCIÓN DEL QUERY ***************

            dt.Dispose()

            Dim datos = New Mensaje With {
            .msg = mostrar
            }

            Return JsonConvert.SerializeObject(datos)

        Catch ex As Exception
            Dim datos = New Mensaje With {
            .msg = "Error al intentar procesar: " & ex.Message
            }

            Return JsonConvert.SerializeObject(datos)

        End Try
    End Function

Hasta ahora creamos el servicio web del lado del servidor y lo que hacemos es recuperar el nombre de la ruta a la que pertenece los clientes, el numero de clientes y el código de cada cliente, veamos como llamarlo desde Javascript usando el método AJAX de JQuery

       function GetLista() {
            var ruta = "RUTA 01";

            var jsonClientes = [];
            var cod_cliente;

            $(".sortable1 li").each(function () {
               cod_cliente = parseInt($(this).children("input").val());
               jsonClientes.push({ "codigo": cod_cliente });
            });

            //console.log(jsonClientes);

            var params = {
                ruta: ruta,
                clientes: JSON.stringify(jsonClientes)
            };

            $.ajax({
                url: '../services/datalist.asmx/sendRutas',
                type: 'POST',
                data: JSON.stringify(params),
                contentType: "application/json; charset=utf-8",
                processData: false,
                success: function (data) {
                    var obj = JSON.parse(data.d);

                    alertify.alert(obj.msg);
                },
                error: function (data) {
                    alertify.error("Error: " + data.responseText);
                }

            });
        }

Podemos observar que en la función de Javascript en el URL llamamos a nuestro método sendRutas y pasamos los parametros en formato JSON con los mismos nombres que hemos declarado en el servicio web.

Por otro lado la lista UL es convertida a un JSON, mediante la funcion each de jquery y se asigna a la variable params que sera enviada al servicio web, buscamos el codigo del cliente a travez del Hidden Fild que tenemos usando la funcion children de jquery.

Finalmente enviamos los datos al servicio web y recuperamos una cadena de texto en formato JSON mostrando los datos principales que tenemos. Con esto, podras crear tu propio codigo para guardar y enviar a la base de datos información o procesarla como sea conveniente.

Suscribir
Notificar a
guest
0 Comentarios
Comentarios en línea
Ver todos los comentarios