没有 HTML 表单的 Laravel 5 AJAX 排序顺序数据(jQuery 可排序)

Posted

技术标签:

【中文标题】没有 HTML 表单的 Laravel 5 AJAX 排序顺序数据(jQuery 可排序)【英文标题】:Laravel 5 AJAX Sort Order data (jQuery Sortable) with no HTML form 【发布时间】:2015-05-18 00:00:25 【问题描述】:

我正在尝试使用 Laravel 5 在我的新网站的帮助中心内为每篇文章存储排序顺序,但在使其正常工作时遇到了一些麻烦。我正在使用 jQuery UI 的 .sortable 来安排页面上的元素,并且由于整个站点中将有多个部分可以对区域进行排序,因此我的 jQuery 脚本是以“一个脚本为所有”的方式构建的目的。因此使用data-* 属性和路由名称引用。

这是我目前得到的代码:

routes.php

Route::post('admin/help-centre/category/category_id/section/section_id/article/sort-order', 'AdminHelpCentreArticleController@sortOrder');

AdminHelpCentreArticleController.php

public function sortOrder($category_id, $section_id)

    /* Return ------------------------------------- */
        return [
            'category_id' => $category_id,
            'section_id' => $section_id
        ];

show.blade.php(管理文章列表)

<ul id="help-center-articles-sort" class="sortable">
    @foreach ($helpCentreArticles as $helpCentreArticle)
        <li class="sortable-element" data-sortable-element-id=" $helpCentreArticle->id ">
            <a href=" action('AdminHelpCentreArticleController@show', array($helpCentreCategory->id, $helpCentreSection->id, $helpCentreArticle->id)) " target="_self"> $helpCentreArticle->title </a>
        </li>
    @endforeach
</ul>

<a href=" $helpCentreSection->id /article/sort-order" target="_self" class="button bm-remove w-full sortable-save" data-sortable-id="help-center-articles-sort">Save Order</a>

scripts.js(包括 CSRF 令牌_token

var csrfToken = $('meta[name="csrf-token"]').attr('content');

$.ajaxPrefilter(function(options, originalOptions, jqXHR) 
    if (options.type.toLowerCase() === 'post')
    
        options.data += options.data?'&':''; // add leading ampersand if `data` is non-empty
        options.data += '_token=' + csrfToken; // add _token entry
    
);

$(document).ready(function() 
    $('.sortable').sortable();

    $('.sortable-save').on('click', function(e) 
        e.preventDefault();

        var route = $(this).attr('href'),
            sortableID = $(this).attr('data-sortable-id');

        var data = $('#' + sortableID + ' .sortable-element').map(function()  
            return $(this).attr('data-sortable-element-id');
        ).get();

        $.ajax(
            type: 'POST',
            url: route,
            dataType: 'json',
            data:  id_array: data ,
            success: function(data) 
                console.log(data);
            , error: function(data) 
                console.log(data);
            ,
        );
    );
);

到目前为止,一切都在控制台中的返回响应方面工作,即Object category_id: "1", section_id: "1"。但是无论我怎么尝试,我似乎都无法通过data 映射到控制器来使用它。

我尝试了一堆猜测,因为我在任何地方都找不到关于 Laravel 5 中 AJAX 的一个像样的教程,并且我尝试了诸如将 $data 参数添加到 sortOrder() 方法之类的方法,我已经尝试了Input::all()Request::all,但都返回错误(我猜是因为它不是实际形式?)。

一旦我将数据传递给控制器​​,我就可以轻松地将排序顺序保存到数据库中。但我还不能完全达到那个阶段,有什么想法吗?

编辑

我应该注意到我确实有一个HelpCentreArticle 模型和一个HelpCentreArticleRequest 请求,以下是每个文件中的一些代码,以防它们也需要:

HelpCentreArticle.php

class HelpCentreArticle extends Model 
    protected $fillable = [
        'category_id',
        'section_id',
        'title',
        'content',
        'excerpt',
        'is_visible',
        'sort_order',
        'created_by',
        'updated_by',
    ];

HelpCentreArticleRequest.php

class HelpCentreArticleRequest extends Request         

    /* Authorization ------------------------------ */
        public function authorize()
        
            return true;
        


    /* Validation rules --------------------------- */
        public function rules()
        
            $rules = [
                'title' => 'required|min:3',
                'content' => 'required|min:10',
            ];

            return $rules;
        


我不确定是否需要将HelpCentreSectionRequest $request 添加为sortOrder() 方法的最后一个参数,因此我可以使用$request-&gt;all(),但它只会在控制台日志中返回422 (Unprocessable Entity)

【问题讨论】:

$_POST['id_array'] 打印什么? @itachi 我确实最终使用 $_POST 来获取数组,它似乎正在工作,它似乎不是用于 Laravel 框架的正确方法,因为您通常使用request/response/input 获取 Laravel 中的 post 数据。 您的问题不需要的代码太多。我想问题是,您正在尝试使用 ajax post 发送 data-* 值但您没有收到它?您将数据作为 id_array: data 在我们的控制器中发送,数据数组可以作为 Input::get('id_array') 检索 我并没有特别看出代码太多,涵盖了我认为逻辑良好的各个方面。但除此之外,使用Input::get(); 是正确的方法,正如我之前尝试过的那样,除了我没有在控制器中包含use Input;。我已将此添加为答案。感谢您的回复,不胜感激。 【参考方案1】:

看来正确的方法是使用Input::get('id_array'); 而不是$_POST['id_array'];,我试过了,但是当我最初尝试这个时,我没有在控制器顶部包含use Input;,正如我所想这已经可以访问了,但不是。

添加use Input; 和使用Input::get(); 现在可以正常工作了。

这是更新后的代码:

AdminHelpCentreArticleController.php

public function sortOrder($category_id, $section_id)


    /* Query Select ------------------------------- */
        $helpCentreCategory = HelpCentreCategory::findOrFail($category_id);
        $helpCentreSection = HelpCentreSection::findOrFail($section_id);


    /* Variables ---------------------------------- */
        $id_array = Input::get('id_array');
        $sort_order = 1;


    /* Query Update ------------------------------- */
        foreach($id_array as $id) 
            $helpCentreArticle = HelpCentreArticle::where('id', $id)->first();

            $helpCentreArticle->sort_order = $sort_order;
            $helpCentreArticle->save();

            $sort_order++;
        


    /* Return ------------------------------------- */
        return ['success' => true];


那么您显然可以访问success 以在您的jQuery 中使用if else 语句来操作页面。

【讨论】:

【参考方案2】:

我使用 Laravel 实现的 UI 可排序

index.blade.php

...
@foreach($photos as $photo)
<tr data-sortable=" $photo->pivot->position " data-id=" $restaurant->id " data-photo-id=" $photo->pivot->photo_id ">
    <td>
        <i class="fa fa-sort" aria-hidden="true"></i>
    </td>
...
</tr>
@endforeach
<script type="text/javascript">
$("#sortable-ui tbody").sortable(
    helper: fixHelper,
    update: function(event, ui) 
        $("#sortable-ui tbody tr").each(function(index)
            console.log($(this).data('id')+', '+(index+1));
            $.ajax(
                url: ' route('owner.photo.update.position') ',
                type: 'POST',
                data: 'restaurant_id='+$(this).data('id')+'&photo_id='+$(this).data('photo-id')+'&position='+(index+1)
            )
            .done(function (response) 
                console.log(response);
            )
            .fail(function (jqXhr) 
                console.log(jqXhr);
            );
        );
    
).disableSelection();
</script>

scripts.js

$.ajaxSetup(
    headers: 
        'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
    
);

AjaxController.php

public function updatePhotoPosition(Request $request)

    $restaurant = $this->restaurantRepository->getById($request->get('restaurant_id'));
    $photoId = $request->get('photo_id');
    $photo = $restaurant
        ->photos()
        ->wherePivot('photo_id', $photoId)
        ->first();

    $photo->pivot->position = $request->get('position');
    $photo->pivot->save();

【讨论】:

以上是关于没有 HTML 表单的 Laravel 5 AJAX 排序顺序数据(jQuery 可排序)的主要内容,如果未能解决你的问题,请参考以下文章

Laravel 5.4:发布没有表单或隐藏 url 的路由

未找到 Laravel 5 类“表单”

Laravel 5:表单数据不会提交到数据库 - 没有显示错误

laravel 5.2 中的表单模型绑定

Laravel 5.5 - 同时验证多个表单请求

Laravel 5 中的登录和注册表单