Hello, I have an application with ASP.NET WEBFORM in which I load a list using the BulletedList control, I can load the data perfectly and applying the Jquery sortable method I can drag and drop the elements and everything is fine.
The problem is that when trying to save the data to SQL SERVER, it gets loaded in the original order and ignores the JQUERY order.
Here my code
<asp:BulletedList ID="blActivos" runat="server" CssClass="sortable sortable1 connectedSortable fl w49Por" RenderWhenDataEmpty="true">
</asp:BulletedList>
<script>
$(function () {
$(".sortable1, .sortable2").sortable({
placeholder: "ui-state-highlight",
connectWith: ".connectedSortable",
items: "li:not(.ui-state-disabled)"
}).disableSelection();
</script>
On the server side, to populate the control I use the following:
Private Sub Load_Clientes_Activos()
Dim sql As String = String.Empty
sql = "EXEC sp_view_cliente_cartera @cod_cartera = " & cod_cartera
Dim dt As DataTable = DataBase.GetDataSet(sql).Tables(0)
Me.blActivos.DataSource = dt
Me.blActivos.DataValueField = "CODIGO" 'Valor Oculto
Me.blActivos.DataTextField = "NOMBRE" 'Valor a Mostrar
Me.blActivos.DataBind()
'Me.ddlFrecuenciaPago.Items.Insert(0, New ListItem("Seleccione...", String.Empty))
dt.Dispose()
Catch ex As Exception
Me.ltMensaje.Text = conn.pmsgBox("Ocurrió un error al intentar cargar los clientes activos en la cartera.", "error")
End Try
End Sub
I hope you can help me
The problem is that when trying to save the data to SQL SERVER, it gets loaded in the original order and ignores the JQUERY order.
Correct, the bulleted list is read only. Inputs are needed to submit the user's selected order to the server. Maybe add a hidden field to the HTML where the value is item Id. If the hidden fields have the same name then the Ids are sent as an array. If you use a data bound control, then loop over the control's item collection to get each item in the collection and read the submitted value(s).
The idea is to take the order of the control and insert that data in that order into the SQL.
I do the same with PHP in a very simple way, but the ViewState of the control does not allow me to replicate
Also use the Listbox control and it is the same result. In the browser I can do the order I want, but when trying to save, the initial order is generated.
We can't see your code. Here's a very basic example using a standard HTML hidden input. The browser submits the hidden field as an array (comma separated values).
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebFormsDemo.jQuerySort.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css" />
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.js"></script>
<script>
$(function () {
$("#sortable").sortable();
</script>
</head>
<form id="form1" runat="server">
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<ui id="sortable">
</HeaderTemplate>
<ItemTemplate>
<li class="ui-state-default">
<span class="ui-icon ui-icon-arrowthick-2-n-s"></span>
<asp:Label ID="Label1" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Item") %>' />
<asp:Label ID="Label2" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "ItemId") %>' />
<input type="hidden" name="Ids" value='<%# DataBinder.Eval(Container.DataItem, "ItemId") %>' />
</ItemTemplate>
<FooterTemplate>
</FooterTemplate>
</asp:Repeater>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
<asp:GridView ID="GridView1" runat="server"></asp:GridView>
</form>
</body>
</html>
Code Behind
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebFormsDemo.jQuerySort
public partial class Default : System.Web.UI.Page
private List<ItemsModel> model;
protected void Page_Load(object sender, EventArgs e)
if (!Page.IsPostBack)
model = PopulateItems();
Repeater1.DataSource = model;
Repeater1.DataBind();
private List<ItemsModel> PopulateItems()
return new List<ItemsModel>()
new ItemsModel() {ItemId=1, Item="Hello", SortOrder=0},
new ItemsModel() {ItemId=2, Item="World", SortOrder=1},
new ItemsModel() {ItemId=3, Item="Foo", SortOrder=2},
new ItemsModel() {ItemId=4, Item="Bar", SortOrder=3},
protected void Button1_Click(object sender, EventArgs e)
int count = 0;
List<RequestItems> requestOrder = new List<RequestItems>();
foreach (object Id in Request.Form["Ids"].Split(','))
RequestItems item = new RequestItems() { ItemId = int.Parse(Id.ToString()), SortOrder = count++ };
requestOrder.Add(item);
GridView1.DataSource = requestOrder;
GridView1.DataBind();
public class ItemsModel
public int ItemId { get; set; }
public string Item { get; set; } = string.Empty;
public int SortOrder { get; set; }
public class RequestItems
public int ItemId { get; set; }
public int SortOrder { get; set; }
The above is an overly simplified example and can be greatly improved.
In the end I decided to create a WebMethod to traverse the control with JQUERY and send the same order visible to the client to the WebMethod and later to the database.
The coigo is cleaner, but the work is more advanced, I think there should be a much easier method for beginners. I greatly appreciate the help and advice.
Greetings.