[扩展推荐] Laravel 使用 rutorika-sortable 和 jQuery Sortable 实现拖拽更改列表顺序

file

项目地址

服务端

一、安装扩展包

composer require rutorika/sortable

二、配置数据库字段

添加 position 字段

public function up()
{
    Schema::create('articles', function (Blueprint $table) {
        // ... 其他字段 ...
        $table->integer('position');  // 数据模型的定位字段,使用此字段来排序
    });
}

如果想自定义 position 字段,请接着看下一步。

三、使用 trait

在你的 Eloquent 数据模型中引入 SortableTrait:

class Article extends Model
{
    use \Rutorika\Sortable\SortableTrait;
}

你可以指定数据模型的 $sortableField 来自定义排序字段。如:

class Article extends Model
{
    use \Rutorika\Sortable\SortableTrait;
    protected static $sortableField = 'somefield';
}

四、路由器入口

Route::post('sort', 'ArticleController@sort')->name('articles.sort');

五、控制器方法


    public function sort(Request $request)
    {
        $entity = Article::findOrFail($request->id);
        $positionEntity = Article::findOrFail($request->positionEntityId);

        if ($request->type == 'moveAfter') {
            $entity->moveAfter($positionEntity);
        } else {
            $entity->moveBefore($positionEntity);
        }

        return ['success' => true];
    }

六、View 部分代码


<table class="ui bottom attached files single line unstackable selectable table sorted_table">
  <tbody>

      @foreach($articles as $article)

        <tr data-itemId="{{ $article->id }}">
          <td>
            <i class="grey content icon move-handler"></i>

            <i class="grey file text outline icon"></i>
            <a href="{{ route('article.show', $article->id) }}">
              {{ $article->title }}
            </a>
          </td>
          <td class="right aligned">
              {{ $article->created_at->diffForHumans() }}
          </td>
        </tr>

      @endforeach

  </tbody>
</table>

前端代码

一、加载 jQuery Sortable

jQuery Sortable http://johnny.github.io/jquery-sortable/

二、JS 代码

<script>

    var changePosition = function(requestData){

        requestData._token = '{{ csrf_token() }}';
        $.ajax({
            'url': '{{ route('articles.sort') }}',
            'type': 'POST',
            'data': requestData,
            'success': function(data) {
                console.log(data);

                if (data.success) {
                    console.log('success');
                } else {
                    console.log('some logic error');
                }
            },
            'error': function(){
                console.log('Request error');
            }
        });
    };

    $('.sorted_table').sortable({
        containerSelector: 'table',
        itemPath: '> tbody',
        itemSelector: 'tr',
        placeholder: '<tr class="placeholder"/>',
        onDrop: function  ($item, container, _super) {

            $item.removeClass(container.group.options.draggedClass).removeAttr("style")
            $("body").removeClass(container.group.options.bodyClass)

            var $previous = $item.prev();
            var $next = $item.next();

            console.log( '$item: ' + $item.data('itemid'));
            console.log( '$previous: ' + $previous.data('itemid'));
            console.log( '$next: ' + $next.data('itemid'));

            if ($previous.length > 0) {
                changePosition({
                    type: 'moveAfter',
                    id: $item.data('itemid'),
                    positionEntityId: $previous.data('itemid')
                });
            } else if ($next.length > 0) {
                changePosition({
                    type: 'moveBefore',
                    id: $item.data('itemid'),
                    positionEntityId: $next.data('itemid')
                });
            } else {
                console.log('something wrong');
            }
        }
    });
</script>

三、样式代码

.sorted_table {
    i.icon.move-handler {
        cursor: move !important;
    }
    tr.placeholder {
      display: block;
      background: red;
      position: relative;
      margin: 0;
      padding: 0;
      border: none;
    }
    tr.placeholder:before {
        content: "";
        position: absolute;
        width: 0;
        height: 0;
        border: 5px solid transparent;
        border-left-color: red;
        margin-top: -5px;
        left: -5px;
        border-right: none;
    }
}

.dragged {
  position: absolute;
  opacity: 0.9;
  z-index: 2000;
}

本作品采用《CC 协议》,转载必须注明作者和本文链接
摈弃世俗浮躁,追求技术精湛
本帖由系统于 5年前 自动加精
Summer
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 6

可以放张 GIF 图 :+1:

7年前 评论

厉害了 为了排序我用的angular

7年前 评论

@Summer,这个打赏功能不好,我打赏了都不能装B,不好用,要改改。

7年前 评论
Summer

@张铁林 得申请微信支付后才能做到记录

7年前 评论
DukeAnn

@张铁林 打赏完手动留言上榜

7年前 评论
Destiny

赞!

7年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!