【问题标题】:Sort table using jquery.ui and store the new position to database使用 jquery.ui 对表进行排序并将新位置存储到数据库
【发布时间】:2025-11-25 05:40:01
【问题描述】:

我有一个名为 categories 的表,用于存储电子商务的类别。该表有以下几个方面:

这是管理类别的用户界面。

我想创建一个系统来使用 JQuery.UI 对该表进行排序。

这是我尝试过的,但它返回给我500(内部服务器错误)

<table class="table table-striped table-hover">
    <thead>
        <tr>
            <th scope="col" span="1">Nombre</th>
            <th scope="col" span="1" class="table-justified hide-mobile">Estado</th>
            <th scope="col" span="1" class="table-opts">Orden</th>
            <th scope="col" span="1"></th>
        </tr>
    </thead>
    <tbody id="table_content">
        foreach($categories as $category)
            <tr data-index="{{$category->id}}" data-position="{{$category->position}}">
                <td class="table-text">{{$category->name}}</td>
                <td class="table-text table-justified hide-mobile">
                    if ($category->visibility)
                        <i class="far fa-eye"></i>
                    else
                        <i class="far fa-eye-slash"></i>
                    endif
                </td>
                <td class="table-text table-opts">{{$category->position}}</td>
                <td class="table-opts">
                    <div class="operations">
                        <a href="{{url('/admin/categories/'.$category->id.'/edit')}}" class="btn-edit pV-8 pH-12" data-bs-toggle="tooltip" data-bs-placement="top" title="Editar">
                            <i class="fas fa-edit"></i>
                        </a>
                        <a href="{{url('/admin/categories/'.$category->id.'/delete')}}" class="btn-delete btn-confirm pV-8 pH-12" data-bs-toggle="tooltip" data-bs-placement="top" title="Eliminar">
                            <i class="fas fa-trash-alt"></i>
                        </a>
                    </div>
                </td>
            </tr>
        endforeach
    </tbody>
</table>

<script type="text/javascript">
    $(document).ready(function(){
        $('#table_content').sortable({
            cancel: 'thead',
            stop: () => {
                var items = $('#table_content').sortable('toArray', {attribute: 'data-index'});
                var ids = $.grep(items, (item) => item !== "");
                $.post('{{ url('/admin/categories_list/reorder') }}', {
                    ": $("meta[name='csrf-token']").attr("content"),
                    ids
                })
                .fail(function (response) {
                    alert('Error occured while sending reorder request');
                    location.reload();
                });
            }
        });
    });
</script>

这是控制器功能:

public function postCategoriesReorder(Request $request){
    $request->validate([
        'ids' => 'required|array',
        'ids.*' => 'integer',
    ]);

    foreach ($request->ids as $index => $id){
        DB::table('categories')->where('id', $id)->update(['position' => $index+1]);
    }

    return response(null, Response::HTTP_NO_CONTENT);
}

【问题讨论】:

    标签: laravel jquery-ui jquery-ui-sortable


    【解决方案1】:

    考虑以下示例。

    var tableData = [{
      id: 1,
      name: "Cat 1",
      visibility: true,
      position: 1
    }, {
      id: 2,
      name: "Cat 2",
      visibility: false,
      position: 2
    }, {
      id: 3,
      name: "Cat 3",
      visibility: true,
      position: 3
    }, {
      id: 4,
      name: "Cat 4",
      visibility: true,
      position: 4
    }, {
      id: 5,
      name: "Cat 5",
      visibility: true,
      position: 5
    }];
    
    $(function() {
      function updateTable(data) {
        $.each(data, function(i, r) {
          var row = $("<tr>", {
            "data-index": r.id
          }).data("row", r).appendTo("#table_content");
          $("<td>", {
            class: "table-text"
          }).html(r.name).appendTo(row);
          $("<td>", {
            class: "table-text table-justified hide-mobile"
          }).html("<i class='fas fa-eye'></i>").appendTo(row);
          if (!r.visibility) {
            $(".fa-eye", row).toggleClass("fa-eye fa-eye-slash");
          }
          $("<td>", {
            class: "table-text table-opts"
          }).html(r.position).appendTo(row);
          $("<td>", {
            class: "table-opts"
          }).appendTo(row);
          $("<div>", {
            class: "operations"
          }).appendTo($("td:last", row));
          $("<a>", {
            href: "/admin/categories/" + r.id + "/edit",
            class: "btn-edit pV-8 pH-12",
            title: "Editor",
            "bs-toggle": "tooltip",
            "bs-placement": "top"
          }).html("<i class='fas fa-edit'></i>").appendTo($("td:last > div", row));
          $("<a>", {
            href: "/admin/categories/" + r.id + "/delete",
            class: "btn-delete btn-confirm pV-8 pH-12",
            title: "Eliminar",
            "bs-toggle": "tooltip",
            "bs-placement": "top"
          }).html("<i class='fas fa-trash-alt'></i>").appendTo($("td:last > div", row));
        });
      }
    
      function gatherData(table) {
        var rows = $("tbody > tr", table);
        var item;
        var results = [];
        rows.each(function(i, el) {
          item = $(el).data("row");
          item.position = i + 1;
          results.push(item);
        });
        return results;
      }
    
      updateTable(tableData);
    
      $('#table_content').sortable({
        cancel: 'thead',
        start: (e, ui) => {
          start = $('#table_content').sortable('toArray', {
            attribute: 'data-index'
          });
        },
        stop: () => {
          ids = gatherData("table");
          console.log(start, ids);
          /*
          $.post('/admin/categories_list/reorder', {
              "csrf-token": $("meta[name = 'csrf-token']").attr("content"),
              ids
            })
            .fail(function(response) {
              alert('Error occured while sending reorder request');
              location.reload();
            });
            */
        }
      });
    });
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.4/css/fontawesome.min.css" integrity="sha384-jLKHWM3JRmfMU0A5x5AkjWkw/EYfGUAGagvnfryNV3F9VqM98XiIH7VBGVoxVSc7" crossorigin="anonymous">
    <link rel="stylesheet" href="//code.jquery.com/ui/1.13.0/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.0/jquery-ui.js"></script>
    
    <table class="table table-striped table-hover">
      <thead>
        <tr>
          <th scope="col" span="1">Nombre</th>
          <th scope="col" span="1" class="table-justified hide-mobile">Estado</th>
          <th scope="col" span="1" class="table-opts">Orden</th>
          <th scope="col" span="1"></th>
        </tr>
      </thead>
      <tbody id="table_content">
      </tbody>
    </table>

    这应该允许您将每个 ID 的新位置传递给脚本,以便更新数据库。

    【讨论】:

    • 我试过这个,但在updateTable(tableData); 上我输入了updateTable($categories); 女巫是我从Controller 获得的数据,它返回Uncaught ReferenceError: $categories is not defined
    • @martibellot 可能是一个 PHP 变量并且不被 JavaScript 读取。无论哪种方式,错误都会报告该变量不存在或未定义。
    • @martibellot 也 updateTable() 主要是为示例构建表数据。你应该不需要使用它。
    • 好吧,我已经用我的代码设置了表格内容,但是用我的代码,我不能使用你的函数gatherData()...,我收到这个错误:Uncaught TypeError: Cannot set properties of undefined (setting 'position')
    最近更新 更多