Laravel 使用 href 提交删除表单

Posted

技术标签:

【中文标题】Laravel 使用 href 提交删除表单【英文标题】:Laravel submit delete form with the press of a href 【发布时间】:2018-01-18 20:04:20 【问题描述】:

我在 Laravel 5.4 中有一个表格,它显示具有删除选项的新闻。 代码如下: news.blade.php

@foreach($news as $article)
   <tr class="text-center">
       <td> $article->title </td>
       <td> $article->created_at </td>
       <td> $article->views </td>
       <td>
          <a class="btn btn-primary btn-flat" href="#">
             <i class="fa fa-pencil-square-o" aria-hidden="true"></i>
          </a>
       </td>
       <td>
           <a class="btn btn-warning btn-flat" href="#" onclick="event.preventDefault(); document.getElementById('delete-form').submit();">
                 <i class="fa fa-lg fa-trash"></i>
           </a>

           <form action=" route('delete-article') " method="POST" id="delete-form" style="display: none;">
                csrf_field()
                <input type="hidden" value=" $article->id " name="id">
           </form>
        </td>
   </tr>
@endforeach

我的问题是我如何告诉 javascript 准确提交紧邻 a href 的表单,因为现在它会提交第一个与 id 匹配的表单,而该 id 并不总是与单击的 td 相同一个href

编辑: 我知道我可以尝试使用 jquery 访问单击的 href 的父级,然后访问它的子窗体或使用 jquery 的关闭功能,但我正在寻找更稳定的东西。

【问题讨论】:

如果任何答案对您有帮助,请将其标记为已接受。如果您自己找到解决方案,请不要犹豫分享! 【参考方案1】:

在做任何事情之前,您的路线应该是(如果尚未完成):Route::delete(...)-&gt;name('delete-article');

我认为你可以这样做:

   <a class="btn btn-warning btn-flat" href="#" onclick="event.preventDefault(); document.getElementById('delete-form- $article->id ').submit();">
         <i class="fa fa-lg fa-trash"></i>
   </a>

   <form action=" route('delete-article') " method="POST" id="delete-form- $article->id " style="display: none;">
        csrf_field()
         method_field('DELETE') 
        <input type="hidden" value=" $article->id " name="id">
   </form>

或者使用 Ajax

@foreach($news as $article)
   <tr class="text-center">
       <td> $article->title </td>
       <td> $article->created_at </td>
       <td> $article->views </td>
       <td>
          <a class="btn btn-primary btn-flat" href="#">
             <i class="fa fa-pencil-square-o" aria-hidden="true"></i>
          </a>
       </td>
       <td>
           <a class="btn btn-warning btn-flat" href="#" onclick="callAjax( $article->id )">
                 <i class="fa fa-lg fa-trash"></i>
           </a>
        </td>
   </tr>
@endforeach

<script>
function callAjax(articleId) 
    $.ajaxSetup(
        headers: 
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        
    )

    $.ajax(
        type: 'POST',
        url: ' route('delete-article') ',
        data: _method: 'DELETE', id: articleId
    )
    .done(function (data) 
        // DO SOMETHING OR NOT
     ).error(function (err) 
        // DO SOMETHING OR NOT
     );


</script>

您必须在文档头中指定&lt;meta name="csrf-token" content=" csrf_token() "&gt;。 (https://laravel.com/docs/5.4/csrf#csrf-x-csrf-token)

【讨论】:

我也想过这种方法,但我又在寻找更稳定的方法。 (如果可能) 你说的更稳定是什么意思? 也许您可以使用 Ajax 而不是每次都指定表单。我编辑我的答案。 这个方法看起来很棘手。这是一种作弊和黑客入侵 @TheAngelM97 看看我的回答。 Ajax 听起来像是在欺骗你?为什么?【参考方案2】:

Benjamin Brasseur 为您提供了一种使用 AJAX 的方法。 (顺便说一句,我认为这并不“棘手”)

但是,使用您当前的 javascript,您似乎只是提交了一个隐藏的表单。为什么不使用真实的表格?

<td>
    <form action=" route('delete-article') " method="POST">
         csrf_field() 

        <input type="hidden" value=" $article->id " name="id" />

        <button type="submit" class="btn btn-warning btn-flat">
             <i class="fa fa-lg fa-trash"></i>
        </button>
    </form>
</td>

如果视觉效果不同,请调整 &lt;form&gt; 的样式(使其成为 inline-block 或其他内容)和 &lt;button&gt; 的样式以匹配您的旧 &lt;a&gt;

【讨论】:

【参考方案3】:

html

<tr id="parent- $article->id ">
  <td> $article->title </td>
  <td> $article->created_at </td>
  <td> $article->views </td>
  <td>
    <a href=" route('route', $article->id) " id=" $article->id " data-method="DELETE" class="delete-btn"><i class="fa fa-fw fa-remove"></i></a>
  </td>
</tr>

在你的脑海中添加:

<meta name="csrf-token" content=" csrf_token() ">

我的脚本与我的刀片模板在同一个文件中 JS

<script>
    $.ajaxSetup(
        headers: 
            'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
        
    );
    $(document).on('click', '.delete-btn', function(e) 
        var $this = $(this),
            $id = $(this).attr('id');

        if (confirm('Are you sure you want to delete this post?')) 
            $.post(
                type: $this.data('method'),
                url: $this.attr('href')
            ).done(function (data) 
                $('#parent-' + $id).slideUp(300, function() 
                    $(this).remove();
                );
            ).fail(function (data) 
                console.log(data);  
            );
        

        e.preventDefault();
    );
    </script>

在你的控制器中

public function destroy($id)

        Article::find($id)->delete();

        return response()->json(['success' => 'Article ID: ' . $id . ' has been deleted']);

您的路线:

Route::delete('/delete/post', 'Controller@destroy')->name('delete');

【讨论】:

【参考方案4】:

HTML

<a href="#" onclick="deleteStudent()" class="nav-link">
    <span><i class="fa fa-fw fa-trash mr-1"></i> Delete Student</span>
</a>
<form id="deleteStudentForm" action=" route( 'students.destroy', $student->id ) " method="post">
    @csrf
    @method('DELETE')
</form>

JavaScript

@section('js_after')
    <script>
        function deleteStudent () 
            event.preventDefault();
            if ( confirm( "Do you really want to delete student '$student->stu_name' ?" ) ) 
                // get delete form
                var deleteForm = document.getElementById( 'deleteStudentForm' );
                // submit delete form
                deleteForm.submit();
             else 
                return false;
            
        
    </script>
@endsection

【讨论】:

以上是关于Laravel 使用 href 提交删除表单的主要内容,如果未能解决你的问题,请参考以下文章

为啥突然表单就提交失败了

laravel 无法删除记录

Laravel 输入类型搜索取消按钮提交表单

Laravel 8 - 此路由不支持 POST 方法。支持的方法:删除

如何修复页面重新加载相同的表单提交与laravel

如何使用 get 方法删除此 Laravel 表单